Commit b351de03 authored by Jens Korinth's avatar Jens Korinth
Browse files

!WIP! Refactor all components

parent 4ee69876
......@@ -5,40 +5,36 @@ import chisel3._
import chisel3.util._
object AxiFifoAdapter {
/**
* Configuration parameters for AxiFifoAdapter.
* @param axi AXI-MM interface parameters.
* @param fifoDepth Depth of the backing FIFO (each element data width wide).
* @param burstSize Number of beats per burst (optional).
* @param size Address wrap-around after size elements (optional).
/** Configuration parameters for AxiFifoAdapter.
* @param axi AXI-MM interface parameters.
* @param fifoDepth Depth of the backing FIFO (each element data width wide).
* @param burstSize Number of beats per burst (optional).
* @param size Address wrap-around after size elements (optional).
**/
sealed case class Configuration(fifoDepth: Int,
burstSize: Option[Int] = None,
size: Option[Int] = None)
/**
* I/O bundle for AxiFifoAdapter.
**/
/** I/O bundle for AxiFifoAdapter. */
class IO(cfg: Configuration)(implicit axi: Axi4.Configuration) extends Bundle {
val maxi = Axi4.Master(axi)
val deq = Decoupled(UInt(axi.dataWidth))
val base = Input(UInt(axi.addrWidth))
val enable = Input(Bool())
val maxi = Axi4.Master(axi)
val deq = Decoupled(UInt(axi.dataWidth))
val base = Input(UInt(axi.addrWidth))
}
/**
* Build an AxiFifoAdapter.
* @param cfg Configuration.
* @return AxiFifoAdapter instance.
/** Build an AxiFifoAdapter.
* @param cfg Configuration.
* @return AxiFifoAdapter instance.
**/
def apply(cfg: Configuration)(implicit axi: Axi4.Configuration, l: Logging.Level): AxiFifoAdapter =
new AxiFifoAdapter(cfg)
/**
* Build an AxiFifoAdapter.
* @param fifoDepth Depth of the backing FIFO (each element data width wide).
* @param burstSize Number of beats per burst (optional).
* @param size Address wrap-around after size elements (optional).
* @return AxiFifoAdapter instance.
/** Build an AxiFifoAdapter.
* @param fifoDepth Depth of the backing FIFO (each element data width wide).
* @param burstSize Number of beats per burst (optional).
* @param size Address wrap-around after size elements (optional).
* @return AxiFifoAdapter instance.
**/
def apply(fifoDepth: Int,
burstSize: Option[Int] = None,
......@@ -47,11 +43,10 @@ object AxiFifoAdapter {
new AxiFifoAdapter(Configuration(fifoDepth = fifoDepth, burstSize = burstSize, size = size))
}
/**
* AxiFifoAdapter is simple DMA engine filling a FIFO via AXI-MM master.
* The backing FIFO is filled continuosly with burst via the master
* interface; the FIFO itself uses handshakes for consumption.
* @param cfg Configuration parameters.
/** AxiFifoAdapter is simple DMA engine filling a FIFO via AXI-MM master.
* The backing FIFO is filled continuosly with bursts via the master
* interface; the FIFO itself uses handshakes for consumption.
* @param cfg Configuration parameters.
**/
class AxiFifoAdapter(cfg: AxiFifoAdapter.Configuration)
(implicit axi: Axi4.Configuration,
......@@ -73,20 +68,22 @@ class AxiFifoAdapter(cfg: AxiFifoAdapter.Configuration)
cfg.size.map(", size = %d".format(_)).getOrElse("")))
val io = IO(new AxiFifoAdapter.IO(cfg))
val en = RegNext(io.enable, init = false.B)
val axi_read :: axi_wait :: Nil = Enum(2)
val fifo = Module(new Queue(UInt(axi.dataWidth), cfg.fifoDepth))
val state = RegInit(axi_wait)
val len = Reg(UInt(log2Ceil(bsz).W))
val ra_hs = Reg(Bool())
val len = RegInit(UInt(log2Ceil(bsz).W), (bsz - 1).U)
val ra_hs = RegInit(Bool(), init = false.B)
val maxi_rlast = io.maxi.readData.bits.last
val maxi_raddr = RegInit(io.base)
val maxi_ravalid = !reset && state === axi_read && !ra_hs
val maxi_ravalid = state === axi_read & ~ra_hs
val maxi_raready = io.maxi.readAddr.ready
val maxi_rready = !reset && state === axi_read && fifo.io.enq.ready
val maxi_rvalid = state === axi_read && io.maxi.readData.valid
val maxi_rready = state === axi_read & fifo.io.enq.ready
val maxi_rvalid = state === axi_read & io.maxi.readData.valid
io.deq <> fifo.io.deq
fifo.io.enq.bits := io.maxi.readData.bits.data
......@@ -110,20 +107,14 @@ class AxiFifoAdapter(cfg: AxiFifoAdapter.Configuration)
io.maxi.writeData.valid := false.B
io.maxi.writeResp.ready := false.B
when (reset) {
state := axi_wait
len := (bsz - 1).U
maxi_raddr := io.base
ra_hs := false.B
}
.otherwise {
when (state === axi_wait && fifo.io.count <= (cfg.fifoDepth - bsz).U) { state := axi_read }
when (en) {
when (state === axi_wait & fifo.io.count <= (cfg.fifoDepth - bsz).U) { state := axi_read }
when (state === axi_read) {
when (maxi_ravalid && maxi_raready) {
when (maxi_ravalid & maxi_raready) {
maxi_raddr := maxi_raddr + (bsz * (axi.dataWidth / 8)).U
ra_hs := true.B
}
when (maxi_rready && maxi_rvalid) {
when (maxi_rready & maxi_rvalid) {
when (maxi_rlast) {
state := Mux(fifo.io.count <= (cfg.fifoDepth - bsz).U, state, axi_wait)
len := (bsz - 1).U
......
package chisel.axiutils
package chisel.axiutils.axi4
import chisel.axi._
import chisel.miscutils._
import chisel3._
import chisel3.util._
import chisel.axi._
object FifoAxiAdapter {
class IO(fifoDepth: Int)(implicit axi: Axi4.Configuration) extends Bundle {
val maxi = Axi4.Master(axi)
val enq = Flipped(Decoupled(UInt(axi.dataWidth)))
val base = Input(UInt(axi.addrWidth))
val count = Output(UInt(log2Ceil(fifoDepth).W))
val enable = Input(Bool())
val maxi = Axi4.Master(axi)
val enq = Flipped(Decoupled(UInt(axi.dataWidth)))
val base = Input(UInt(axi.addrWidth))
val count = Output(UInt(log2Ceil(fifoDepth).W))
}
}
class FifoAxiAdapter(fifoDepth: Int,
burstSize: Option[Int] = None,
size: Option[Int] = None)
(implicit axi: Axi4.Configuration) extends Module {
(implicit axi: Axi4.Configuration,
logLevel: Logging.Level) extends Module with Logging {
val bsz = burstSize getOrElse fifoDepth
......@@ -26,31 +29,32 @@ class FifoAxiAdapter(fifoDepth: Int,
"burst size (%d) must be 0 < bsz <= FIFO depth (%d) <= 256"
.format(bsz, fifoDepth))
println ("FifoAxiAdapter: fifoDepth = %d, address bits = %d, data bits = %d, id bits = %d%s%s"
.format(fifoDepth, axi.addrWidth:Int, axi.dataWidth:Int, axi.idWidth:Int,
burstSize.map(", burst size = %d".format(_)).getOrElse(""),
size.map(", size = %d".format(_)).getOrElse("")))
cinfo("FifoAxiAdapter: fifoDepth = %d, address bits = %d, data bits = %d, id bits = %d%s%s"
.format(fifoDepth, axi.addrWidth:Int, axi.dataWidth:Int, axi.idWidth:Int,
burstSize.map(", burst size = %d".format(_)).getOrElse(""),
size.map(", size = %d".format(_)).getOrElse("")))
val io = IO(new FifoAxiAdapter.IO(fifoDepth))
val en = RegNext(io.enable, init = false.B)
val axi_write :: axi_wait :: Nil = Enum(2)
val fifo = Module(new Queue(UInt(axi.dataWidth), fifoDepth))
val state = RegInit(axi_wait)
val len = Reg(UInt(log2Ceil(bsz).W))
val maxi_wlast = state === axi_write && len === 0.U
val len = RegInit(UInt(log2Ceil(bsz).W), init = (bsz - 1).U)
val maxi_wlast = state === axi_write & len === 0.U
val maxi_waddr = RegInit(io.base)
val maxi_wavalid = !reset && fifo.io.count >= bsz.U
val maxi_wavalid = fifo.io.count >= bsz.U
val maxi_waready = io.maxi.writeAddr.ready
val maxi_wready = state === axi_write && io.maxi.writeData.ready
val maxi_wvalid = state === axi_write && fifo.io.deq.valid
val maxi_wready = state === axi_write & io.maxi.writeData.ready
val maxi_wvalid = state === axi_write & fifo.io.deq.valid
io.enq <> fifo.io.enq
io.maxi.writeData.bits.last := maxi_wlast
io.maxi.writeData.bits.data := fifo.io.deq.bits
io.maxi.writeData.valid := maxi_wvalid
io.maxi.writeAddr.valid := maxi_wavalid
fifo.io.deq.ready := state === axi_write && io.maxi.writeData.ready
fifo.io.deq.ready := state === axi_write & io.maxi.writeData.ready
io.count := fifo.io.count
// AXI boilerplate
......@@ -70,13 +74,13 @@ class FifoAxiAdapter(fifoDepth: Int,
io.maxi.readAddr.valid := false.B
io.maxi.readData.ready := false.B
when (reset) {
state := axi_wait
len := (bsz - 1).U
}
.otherwise {
when (state === axi_wait && fifo.io.count >= bsz.U) { state := axi_write }
when (maxi_wavalid && maxi_waready) {
when (en) {
when (state === axi_wait) {
when (fifo.io.count >= bsz.U | (fifo.io.count > 0.U & ~fifo.io.deq.valid)) {
state := axi_write
}
}
when (maxi_wavalid & maxi_waready) {
val addr_off = (bsz * (axi.dataWidth / 8)).U
val next_addr = maxi_waddr + addr_off
if (size.isEmpty)
......@@ -85,10 +89,10 @@ class FifoAxiAdapter(fifoDepth: Int,
maxi_waddr := Mux(next_addr >= io.base + size.get.U, io.base, next_addr)
}
when (state === axi_write) {
when (maxi_wready && maxi_wvalid) {
when (maxi_wready & maxi_wvalid) {
when (maxi_wlast) {
state := Mux(fifo.io.count >= bsz.U, state, axi_wait)
len := (bsz - 1).U
len := fifo.io.count - 1.U
}
.otherwise { len := len - 1.U }
}
......
......@@ -4,14 +4,14 @@ import chisel3.util._
import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
import chisel.axi._
import chisel.axiutils._
import org.scalatest.junit.JUnitSuite
import chisel.miscutils.{DecoupledDataSource, Logging}
import org.scalatest.prop.Checkers
import org.scalacheck.Prop._
import scala.math.{random, pow}
/**
* Composite test module:
* Uses FifoAxiAdapter to fill SlaveModel; then reads data from
* SlaveModel via AxiFifoAdapter.
/** Composite test module:
* Uses FifoAxiAdapter to fill SlaveModel; then reads data from
* SlaveModel via AxiFifoAdapter.
**/
class Axi2AxiModule(val fifoDepth: Int = 16, val size: Option[Int])
(implicit axi: Axi4.Configuration, l: Logging.Level)
......@@ -26,28 +26,28 @@ class Axi2AxiModule(val fifoDepth: Int = 16, val size: Option[Int])
val sz = size.getOrElse(pow(2, axi.addrWidth.toDouble).toInt / axi.dataWidth)
val aw = Seq(axi.addrWidth:Int, log2Ceil(sz * (axi.dataWidth / 8))).min
cinfo ("Axi2AxiModule: address bits = %d, size = %d".format(aw, sz))
val cfg = SlaveModel.Configuration()
val cfg = SlaveModel.Configuration(size = Some(sz), readDelay = 0, writeDelay = 0)
val data = 0 to sz map (n => n % pow(2, axi.dataWidth:Int).toInt)
val dsrc = Module(new DecoupledDataSource(
gen = UInt(axi.dataWidth),
size = sz,
data = data map (_.U),
repeat = false))
val dsrc = Module(new DecoupledDataSource(gen = UInt(axi.dataWidth),
size = sz,
data = data map (_.U),
repeat = false))
val fad = Module(new FifoAxiAdapter(fifoDepth = sz, burstSize = Some(fifoDepth)))
val saxi = Module(new SlaveModel(cfg))
val afa = Module(AxiFifoAdapter(fifoDepth = fifoDepth))
val base = 0.U(aw.W)
fad.io.enq <> dsrc.io.out
fad.io.enable := true.B
fad.io.enq <> dsrc.io.out
saxi.io.saxi.writeAddr <> fad.io.maxi.writeAddr
saxi.io.saxi.writeData <> fad.io.maxi.writeData
saxi.io.saxi.writeResp <> fad.io.maxi.writeResp
saxi.io.saxi.readAddr <> afa.io.maxi.readAddr
saxi.io.saxi.readData <> afa.io.maxi.readData
// FIXME afa.reset := dsrc.io.out.valid || fad.fifo.io.count > 0.U
afa.io.enable := ~dsrc.io.out.valid //| fad.io.count > 0.U
fad.io.base := base
afa.io.base := base
io.deq <> afa.io.deq
......@@ -90,23 +90,30 @@ class Axi2AxiTester(m: Axi2AxiModule)
}
/** Test suite using both AxiFifoAdapter and FifoAxiAdapter. **/
class Axi2AxiSuite extends ChiselFlatSpec {
class Axi2AxiSuite extends ChiselFlatSpec with Checkers {
import java.nio.file._
implicit val logLevel = chisel.miscutils.Logging.Level.Warn
implicit val logLevel = chisel.miscutils.Logging.Level.Info
behavior of "AxiFifoAdapter and FifoAxiAdapter"
def run(size: Int, fifoDepth: Int, addrWidth: Int, dataWidth: Int) {
def run(size: Int, fifoDepth: Int, addrWidth: Int, dataWidth: Int): Boolean = {
implicit val axi = Axi4.Configuration(addrWidth = AddrWidth(addrWidth), dataWidth = DataWidth(dataWidth))
val dir = Paths.get("test")
.resolve("s%d_aw%d_dw%d".format(size, addrWidth, axi.dataWidth:Int))
.toString
try {
Driver.execute(Array("--fint-write-vcd", "--target-dir", dir),
() => new Axi2AxiModule(fifoDepth = fifoDepth,
size = Some(size)))
{ m => new Axi2AxiTester(m) }
} catch { case ex: Throwable =>
ex.getStackTrace() foreach (println(_))
throw ex
}
}
"run8bit" should "be ok" in { run (size = 256, fifoDepth = 4, addrWidth = 32, dataWidth = 8) }
"run16bit" should "be ok" in { run (size = 256, fifoDepth = 8, addrWidth = 32, dataWidth = 16) }
it should "be ok" in { check(run (size = 8, fifoDepth = 4, addrWidth = 32, dataWidth = 8)) }
//"run8bit" should "be ok" in { check(run (size = 256, fifoDepth = 4, addrWidth = 32, dataWidth = 8)) }
/*"run16bit" should "be ok" in { run (size = 256, fifoDepth = 8, addrWidth = 32, dataWidth = 16) }
"run32bit" should "be ok" in { run (size = 256, fifoDepth = 8, addrWidth = 32, dataWidth = 32) }
"run64bit" should "be ok" in { run (size = 1024, fifoDepth = 256, addrWidth = 32, dataWidth = 64) }
"run64bit" should "be ok" in { run (size = 1024, fifoDepth = 256, addrWidth = 32, dataWidth = 64) }*/
}
package chisel.axiutils.axi4
import chisel.axiutils._
import chisel.miscutils._, chisel.miscutils.generators._
import chisel3._, chisel3.util._
import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
import java.nio.file.Paths
import chisel.axi._
import org.scalacheck._, org.scalacheck.Prop._
import org.scalatest.prop.Checkers
class AxiFifoAdapterModule1(val fifoDepth: Int, val blockSize: Int)
(implicit axi: Axi4.Configuration,
logLevel: Logging.Level) extends Module {
val addrWidth = Seq(log2Ceil(axi.dataWidth * fifoDepth * blockSize / 8), 1).max
val cfg = SlaveModel.Configuration(size = Some(Math.pow(2, addrWidth:Int).toInt))
val saxi = Module (new SlaveModel(cfg))
val io = IO(new Bundle {
val dqr = Output(Bool())
val afa_en = Input(Bool())
val afa_deq_valid = Output(Bool())
val afa_deq_bits = Output(UInt(axi.dataWidth))
val saxi_debug = saxi.io.debug.cloneType
})
val afa = Module (AxiFifoAdapter(fifoDepth = fifoDepth))
val dqr = RegInit(true.B)
afa.io.base := 0.U
//afa.io.deq.ready := true.B
afa.io.deq.ready := dqr
afa.io.maxi <> saxi.io.saxi
dqr := io.dqr
io.afa_deq_valid := afa.io.deq.valid
io.afa_deq_bits := afa.io.deq.bits
io.saxi_debug <> saxi.io.debug
}
class AxiFifoAdapterModule1Test(m: AxiFifoAdapterModule1)
(implicit axi: Axi4.Configuration) extends PeekPokeTester(m) {
private var _cc = 0
// re-define step to output progress info
override def step(n: Int) {
super.step(n)
_cc += n
if (cc % 1000 == 0) println("clock cycle: " + _cc)
}
poke(m.io.afa_en, false.B)
reset(10)
// setup data
println("prepping %d (%d x %d) mem elements ...".format(m.fifoDepth * m.blockSize, m.fifoDepth, m.blockSize))
poke(m.io.saxi_debug.r, false.B)
poke(m.io.saxi_debug.ra, 0)
poke(m.io.saxi_debug.w, true.B)
for (i <- 0 until m.fifoDepth * m.blockSize) {
poke(m.io.saxi_debug.wa, i % math.pow(2, axi.dataWidth:Int).toInt)
poke(m.io.saxi_debug.din, i)
step(1)
//pokeAt(m.saxi.mem, i % scala.math.pow(2, axi.dataWidth:Int).toInt, i)
}
poke(m.io.saxi_debug.w, false.B)
poke(m.io.saxi_debug.r, false.B)
poke(m.io.afa_en, true.B)
var res: List[BigInt] = List()
var cc: Int = m.fifoDepth * m.blockSize * 10 // upper bound on cycles
poke(m.io.dqr, true)
while (cc > 0 && res.length < m.fifoDepth * m.blockSize) {
if (peek(m.io.afa_deq_valid) != 0) {
val v: BigInt = peek(m.io.afa_deq_bits)
res ++= List(v)
poke(m.io.dqr, false)
step(res.length % 20)
poke(m.io.dqr, true)
}
step(1)
cc -= 1
}
step(10) // settle
res.zipWithIndex map (_ match { case (v, i) =>
println("#%d: 0x%x (0b%s)".format(i, v, v.toString(2)))
})
poke(m.io.saxi_debug.r, true.B)
step(1)
for (i <- 0 until res.length /*if res(i) != peekAt(m.saxi.mem, i)*/) {
poke(m.io.saxi_debug.ra, i)
step(1)
val v = peek(m.io.saxi_debug.dout)
val msg = "Mem[%03d] = %d (expected %d)".format(i, res(i), v)
println(msg)
expect(res(i) == v/*peekAt(m.saxi.mem, i)*/, msg)
}
}
class AxiFifoAdapterSuite extends ChiselFlatSpec with Checkers {
implicit val logLevel = Logging.Level.Info
def runTest(dataWidth: Int, fifoDepth: Int, blockSize: Int): Boolean = {
val dir = Paths.get("test").resolve("dw%d_fd%d_bs%d".format(dataWidth, fifoDepth, blockSize)).toString
implicit val axi = Axi4.Configuration(dataWidth = DataWidth(dataWidth), addrWidth = AddrWidth(32))
Driver.execute(Array("--fint-write-vcd", "--target-dir", dir),
() => new AxiFifoAdapterModule1(fifoDepth = fifoDepth, blockSize = blockSize))
{ m => new AxiFifoAdapterModule1Test(m) }
}
behavior of "AxiFifoAdapter"
/*it should "read data in correct order for arbitrary configurations" in
check(forAll(bitWidthGen(128), genLimited(1, 8) map (1 << _)) { case (bw, fd) =>
println("Testing with %d bit and %d FIFO depth".format(bw:Int, fd:Int))
runTest(bw, fd, 256)
})*/
it should "be ok" in { runTest(dataWidth = 32, fifoDepth = 1, blockSize = 256/1) }
/*"checkDw32Fd8Bs32" should "be ok" in { runTest(dataWidth = 32, fifoDepth = 8, blockSize = 256/8) }
"checkDw8Fd8Bs32" should "be ok" in { runTest(dataWidth = 8, fifoDepth = 8, blockSize = 256/8) }
"checkDw8Fd2Bs128" should "be ok" in { runTest(dataWidth = 8, fifoDepth = 2, blockSize = 256/2) }
"checkDw64Fd16Bs512" should "be ok" in { runTest(dataWidth = 64, fifoDepth = 16, blockSize = 512) }
"checkDw128Fd128Bs1024" should "be ok" in { runTest(dataWidth = 128, fifoDepth = 128, blockSize = 1024/128) }
// FIXME seems to work, but too slow
// "checkDw8Fd1080Bs480" should "be ok" in { runTest(dataWidth = 8, fifoDepth = 256, blockSize = 480*4) }*/
}
......@@ -51,7 +51,7 @@ class AxiMuxReadTestModule(val n: Int)
class AxiMuxReadTester(m: AxiMuxReadTestModule)
(implicit axi: Axi4.Configuration) extends PeekPokeTester(m) {
implicit val tester = this
SlaveModel.fillWithLinearSeq(m.saxi, axi.dataWidth)
//SlaveModel.fillWithLinearSeq(m.saxi, axi.dataWidth)
reset(10)
var counter: Array[Int] = Array.fill[Int](m.n)(0)
......
package chisel.axiutils.axi4
import generators._, chisel.miscutils.generators._
import chisel.miscutils._
import chisel.axi._
import chisel3._
import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
import org.scalatest.prop.Checkers
import org.scalacheck._, org.scalacheck.Prop._
class FifoAxiAdapterTest(fifoDepth: Int, val data: Seq[BigInt], repeat: Boolean)
(implicit axi: Axi4.Configuration,
logLevel: Logging.Level) extends Module {
val m = Module(new FifoAxiAdapter(fifoDepth))
val src = Module(new DecoupledDataSource(UInt(axi.dataWidth), data.length, data map (_.U), repeat))
val dst = Module(new SlaveModel(SlaveModel.Configuration(readDelay = 0, writeDelay = 0)))
val io = IO(new Bundle {
val debug = dst.io.debug.cloneType
})
src.io.out <> m.io.enq
m.io.base := 0.U
m.io.maxi <> dst.io.saxi
dst.io.debug <> io.debug
}
class FifoAxiAdapterTester(m: FifoAxiAdapterTest) extends PeekPokeTester(m) {
implicit val tester = this
poke(m.io.debug.w, false)
poke(m.io.debug.r, false)
reset(10)
step(m.data.length * 50)
poke(m.io.debug.r, true)
0 until m.data.length foreach { i =>
poke(m.io.debug.ra, i)
step(1)
expect(m.io.debug.dout, m.data(i), s"wrong data at $i")
}
step(10)
}
class FifoAxiAdapterSpec extends ChiselFlatSpec with Checkers {
implicit val logLevel = Logging.Level.Info
behavior of "FifoAxiAdapter"
it should "say hello" in {
check({ println("hello!"); true })
}
it should "work with arbitrary configurations" in
check(forAll(axi4CfgGen, fifoDepthGen) { case (axi4, fd) =>
forAllNoShrink(dataGen(BitWidth(axi4.dataWidth.width)(1024))) { data =>
implicit val a = axi4
try {
Driver.execute(Array("--fint-write-vcd", "--target-dir", "test/axi4/FifoAxiAdapter"),
() => new FifoAxiAdapterTest(fd, data, false))
{ m => new FifoAxiAdapterTester(m) }
} catch { case t: Throwable =>
t.getStackTrace() foreach (println(_))
throw t
}
}})
}
......@@ -5,26 +5,14 @@ import chisel.axi._
import chisel.miscutils.Logging
import scala.util.Properties.{lineSeparator => NL}
class DebugIO(implicit axi: Axi4.Configuration) extends Bundle {
val ra = Input(UInt(axi.addrWidth))
val r = Input(Bool())
val dout = Output(UInt(axi.dataWidth))
val wa = Input(UInt(axi.addrWidth))
val w = Input(Bool())
val din = Input(UInt(axi.dataWidth))
override def cloneType = { new DebugIO()(axi).asInstanceOf[this.type] }
}
object SlaveModel {
/**
* SlaveModelConfiguration configures an SlaveModel instance.
* @param addrWidth address bits for AXI4 interface.
* @param dataWidth word width for AXI4 interface.
* @param idWidth id bits for AXI4 interface.
* @param size size of memory to model (in dataWidth-sized elements).
* @param readDelay simulated delay between read address handshake and data.
* @param writeDelay simulated delay between write address handshake and data.
/** SlaveModelConfiguration configures an SlaveModel instance.
* @param addrWidth address bits for AXI4 interface.
* @param dataWidth word width for AXI4 interface.
* @param idWidth id bits for AXI4 interface.
* @param size size of memory to model (in dataWidth-sized elements).
* @param readDelay simulated delay between read address handshake and data.
* @param writeDelay simulated delay between write address handshake and data.
**/
class Configuration(val size: Int,
val readDelay: Int,
......@@ -42,12 +30,11 @@ object SlaveModel {
}
object Configuration {
/**
* Construct a Configuration. Size and address width are optional,
* but one needs to be supplied to determine simulated memory size.
* @param size size of memory to model in bytes (optional).
* @param readDelay simulated delay between read address handshake and data (default: 30).
* @param writeDelay simulated delay between write address handshake and data (default: 20).
/** Construct a Configuration. Size and address width are optional,
* but one needs to be supplied to determine simulated memory size.
* @param size size of memory to model in bytes (optional).
* @param readDelay simulated delay between read address handshake and data (default: 30).
* @param writeDelay simulated delay between write address handshake and data (default: 20).