Commit 441095fb authored by Jens Korinth's avatar Jens Korinth
Browse files

Refactoring, clean-up

*  split into subpackages axi4 and axi4lite
*  moved each module into its subpackage
*  shortened names by removing Axi-prefixes wherever possible
*  moved Configs and IOs into corresponding companion object
*  replaced some printlns/printfs with Logging facilities
parent 82e7d31a
package chisel.axiutils
/**
* Configuration parameters for AXI-MM interfaces (slave, master).
* @param addrWidth Width of address line(s) in bits.
* @param dataWidth Width of data line(s) in bits.
* @param idWidth Width of id line(s) in bits.
**/
case class AxiConfiguration(addrWidth: Int, dataWidth: Int, idWidth: Int) {
require (addrWidth > 0 && addrWidth <= 128, "addrWidth (%d) must be 0 < addrWidth <= 128 bits".format(addrWidth))
require (dataWidth > 0 && dataWidth <= 128, "dataWidth (%d) must be 0 < dataWidth <= 128 bits".format(dataWidth))
require (idWidth > 0 && idWidth <= 128, "idWidth (%d) must be 0 < idWidth <= 128 bits".format(idWidth))
}
package chisel.axiutils
import chisel.axiutils.registers._
import chisel.axiutils.axi4lite._
import chisel.packaging._, chisel.packaging.CoreDefinition.root
import chisel.miscutils.DecoupledDataSource
import chisel.miscutils.DecoupledDataSource, chisel.miscutils.Logging
import scala.sys.process._
import java.nio.file.Paths
import chisel3._
......@@ -9,6 +9,7 @@ import chisel.axi._
class FifoAxiAdapterTest1(dataWidth: Int, size: Int) extends Module {
val addrWidth = 32
implicit val logLevel = Logging.Level.Info
implicit val axi = Axi4.Configuration(AddrWidth(addrWidth),
DataWidth(dataWidth),
IdWidth(1))
......@@ -30,12 +31,13 @@ class FifoAxiAdapterTest1(dataWidth: Int, size: Int) extends Module {
}
object AxiModuleBuilder extends ModuleBuilder {
implicit val logLevel = Logging.Level.Info
implicit val axi = Axi4.Configuration(AddrWidth(32),
DataWidth(64),
IdWidth(1))
implicit val axilite = Axi4Lite.Configuration(AddrWidth(32),
Axi4Lite.Width32)
val exampleRegisterFile = new Axi4LiteRegisterFileConfiguration(addrGranularity = 8, regs = Map(
val exampleRegisterFile = new axi4lite.RegisterFile.Configuration(addrGranularity = 8, regs = Map(
0 -> new ConstantRegister(value = BigInt("10101010", 16)),
4 -> new ConstantRegister(value = BigInt("20202020", 16)),
8 -> new ConstantRegister(value = BigInt("30303030", 16)),
......@@ -88,7 +90,7 @@ object AxiModuleBuilder extends ModuleBuilder {
None,
() => {
implicit val axi = Axi4.Configuration(AddrWidth(32), DataWidth(64), IdWidth(1))
new AxiSlidingWindow(AxiSlidingWindowConfiguration(
new SlidingWindow(SlidingWindow.Configuration(
gen = UInt(8.W),
width = 8,
depth = 3,
......@@ -116,15 +118,15 @@ object AxiModuleBuilder extends ModuleBuilder {
),
ModuleDef( // AXI Register File
Some(exampleRegisterFile),
() => new Axi4LiteRegisterFile(exampleRegisterFile),
() => new RegisterFile(exampleRegisterFile),
CoreDefinition.withActions(
name = "Axi4LiteRegisterFile",
name = "RegisterFile",
vendor = "esa.cs.tu-darmstadt.de",
library = "chisel",
version = "0.1",
root = root("Axi4LiteRegisterFile"),
root = root("RegisterFile"),
postBuildActions = Seq(_ match {
case Some(cfg: Axi4LiteRegisterFileConfiguration) => cfg.dumpAddressMap(root("Axi4LiteRegisterFile"))
case Some(cfg: RegisterFile.Configuration) => cfg.dumpAddressMap(root("RegisterFile"))
case _ => ()
})
)
......
......@@ -4,39 +4,34 @@ import chisel.axi._
import chisel3._
import chisel3.util._
/**
* Configuration parameters for an AxiSlidingWindow.
* @param gen Underlying element type.
* @param width Width of gen type in bits (TODO infer bitwidth of gen)
* @param depth Depth of the sliding window (accessible elements).
* @param axicfg AXI interface configuration.
**/
sealed case class AxiSlidingWindowConfiguration[T <: Data](
gen: T,
width: Int,
depth: Int,
afa: AxiFifoAdapterConfiguration
)
object SlidingWindow {
/** Configuration parameters for a SlidingWindow.
* @param gen Underlying element type.
* @param width Width of gen type in bits (TODO infer bitwidth of gen)
* @param depth Depth of the sliding window (accessible elements).
* @param axicfg AXI interface configuration.
**/
sealed case class Configuration[T <: Data](gen: T,
width: Int,
depth: Int,
afa: AxiFifoAdapterConfiguration)
/**
* I/O Bundle for an AxiSlidingWindow:
* Consists of base address input, AXI master interface and access
* to the elements of the sliding window.
* @param cfg Configuration parameters.
**/
class AxiSlidingWindowIO[T <: Data](cfg: AxiSlidingWindowConfiguration[T])
(implicit axi: Axi4.Configuration) extends Bundle {
val base = Input(UInt(axi.addrWidth))
val maxi = Axi4.Master(axi)
val data = Decoupled(Vec(cfg.depth, cfg.gen))
def renameSignals() = {
base.suggestName("BASE")
data.ready.suggestName("DATA_READY")
data.valid.suggestName("DATA_VALID")
for (i <- 0 until cfg.depth) data.bits(i).suggestName("DATA_%02d".format(i))
//maxi.renameSignals(None, None)
/**
* I/O Bundle for an AxiSlidingWindow:
* Consists of base address input, AXI master interface and access
* to the elements of the sliding window.
* @param cfg Configuration parameters.
**/
class IO[T <: Data](cfg: Configuration[T])
(implicit axi: Axi4.Configuration) extends Bundle {
val base = Input(UInt(axi.addrWidth))
val maxi = Axi4.Master(axi)
val data = Decoupled(Vec(cfg.depth, cfg.gen))
}
def apply[T <: Data](cfg: SlidingWindow.Configuration[T])
(implicit axi: Axi4.Configuration): SlidingWindow[T] =
new SlidingWindow(cfg)
}
/**
......@@ -48,10 +43,9 @@ class AxiSlidingWindowIO[T <: Data](cfg: AxiSlidingWindowConfiguration[T])
* one element.
* @param cfg Configuration parameters.
**/
class AxiSlidingWindow[T <: Data](val cfg: AxiSlidingWindowConfiguration[T])
(implicit axi: Axi4.Configuration) extends Module {
val io = IO(new AxiSlidingWindowIO(cfg))
io.renameSignals()
class SlidingWindow[T <: Data](val cfg: SlidingWindow.Configuration[T])
(implicit axi: Axi4.Configuration) extends Module {
val io = IO(new SlidingWindow.IO(cfg))
/** AXI DMA engine **/
val afa = Module(AxiFifoAdapter(cfg.afa))
......@@ -100,10 +94,3 @@ class AxiSlidingWindow[T <: Data](val cfg: AxiSlidingWindowConfiguration[T])
}
}
}
/** AxiSlidingWindow companion object: Factory methods. **/
object AxiSlidingWindow {
def apply[T <: Data](cfg: AxiSlidingWindowConfiguration[T])
(implicit axi: Axi4.Configuration): AxiSlidingWindow[T] =
new AxiSlidingWindow(cfg)
}
......@@ -3,35 +3,29 @@ import chisel3._
import chisel3.util._
import chisel.axi.Axi4._
/**
* I/O Bundle for AXI mux.
* @param n Number of slave interfaces.
* @param axi Implicit AXI interface configuration.
**/
class AxiMuxIO(n: Int)(implicit axi: Configuration) extends Bundle {
val saxi = Vec(n, Slave(axi))
val maxi = Master(axi)
/*jdef renameSignals() = {
for (i <- 0 until n)
saxi(i).renameSignals(Some("S%02d_".format(i)), None)
maxi.renameSignals(None, None)
}*/
object AxiMux {
/** I/O Bundle for AXI mux.
* @param n Number of slave interfaces.
* @param axi Implicit AXI interface configuration.
**/
class IO(n: Int)(implicit axi: Configuration) extends Bundle {
val saxi = Vec(n, Slave(axi))
val maxi = Master(axi)
}
}
/**
* AxiMux: Connect n AXI-MM masters to one AXI-MM slave.
* @param n Number of slave interfaces.
* @param axi Implicit AXI interface configuration.
/** Connect n AXI-MM masters to one AXI-MM slave.
* @param n Number of slave interfaces.
* @param axi Implicit AXI interface configuration.
**/
class AxiMux(n: Int)(implicit axi: Configuration) extends Module {
val io = IO(new AxiMuxIO(n))
//io.renameSignals()
val io = IO(new AxiMux.IO(n))
// states of the FSM
val waiting :: in_burst :: Nil = Enum(2)
val r_curr = Reg(UInt(log2Ceil(n).W))
val w_curr = Reg(UInt(log2Ceil(n).W))
val r_curr = Reg(UInt(log2Ceil(n).W))
val w_curr = Reg(UInt(log2Ceil(n).W))
val r_state = RegInit(waiting)
val w_state = RegInit(waiting)
......
package chisel.axiutils.registers
import chisel.axi._, Axi4Lite._
import chisel.axiutils.registers._
package chisel.axiutils.axi4lite
import chisel.axi._, chisel.axi.Axi4Lite
import chisel.miscutils.Logging
import chisel3._
import chisel3.util._
import scala.util.Properties.{lineSeparator => NL}
/** Configuration object for Axi4LiteRegisterFile.
* @param addrGranularity Smallest addressable bit width (default: 8, e.g., 1 byte).
* @param width Register data width (in bits).
* @param regs Map from offsets in addrGranularity to register implementations.
**/
case class Axi4LiteRegisterFileConfiguration(addrGranularity: Int = 32, regs: Map[Int, ControlRegister])
(implicit axi: Configuration) {
/* internal helpers: */
private def overlap(p: (BitRange, BitRange)) = p._1.overlapsWith(p._2)
private def makeRange(a: Int): BitRange = BitRange(a * addrGranularity + axi.dataWidth.toInt - 1, a * addrGranularity)
private lazy val m = regs.keys.toList.sorted map makeRange
private lazy val o: Seq[Boolean] = (m.take(m.length - 1) zip m.tail) map overlap
/* constraint checking */
require (regs.size > 0, "regs must not be empty")
require (regs.size == 1 || !(o reduce (_||_)), "ranges must not overlap: " + regs)
/** Minimum bit width of address lines. */
lazy val minAddrWidth: AddrWidth =
AddrWidth(Seq(log2Ceil(regs.size * axi.dataWidth.toInt / addrGranularity), log2Ceil(regs.keys.max)).max)
/** Dumps address map as markdown file. **/
def dumpAddressMap(path: String) = {
def mksz(s: String, w: Int) = if (s.length > w) s.take(w) else if (s.length < w) s + (" " * (w - s.length)) else s
val fw = new java.io.FileWriter(java.nio.file.Paths.get(path).resolve("AdressMap.md").toString)
fw.append("| **Name** |**From**|**To** | **Description** |").append(NL)
.append("|:----------------|:------:|:------:|:-----------------------------------------|").append(NL)
for (off <- regs.keys.toList.sorted; reg = regs(off))
fw.append("| %s | 0x%04x | 0x%04x | %s |".format(
mksz(reg.name.getOrElse("N/A"), 15), off, off + axi.dataWidth / 8 - 1, reg.description
)).append(NL)
fw.flush()
fw.close
object RegisterFile {
/** Configuration object for RegisterFiles.
* @param addrGranularity Smallest addressable bit width (default: 8, e.g., 1 byte).
* @param width Register data width (in bits).
* @param regs Map from offsets in addrGranularity to register implementations.
**/
case class Configuration(addrGranularity: Int = 32, regs: Map[Int, ControlRegister])
(implicit axi: Axi4Lite.Configuration) {
/* internal helpers: */
private def overlap(p: (BitRange, BitRange)) = p._1.overlapsWith(p._2)
private def makeRange(a: Int): BitRange =
BitRange(a * addrGranularity + axi.dataWidth.toInt - 1, a * addrGranularity)
private lazy val m = regs.keys.toList.sorted map makeRange
private lazy val o: Seq[Boolean] = (m.take(m.length - 1) zip m.tail) map overlap
/* constraint checking */
require (regs.size > 0, "regs must not be empty")
require (regs.size == 1 || !(o reduce (_||_)), "ranges must not overlap: " + regs)
/** Minimum bit width of address lines. */
lazy val minAddrWidth: AddrWidth =
AddrWidth(Seq(log2Ceil(regs.size * axi.dataWidth.toInt / addrGranularity), log2Ceil(regs.keys.max)).max)
/** Dumps address map as markdown file. **/
def dumpAddressMap(path: String) = {
def mksz(s: String, w: Int) = if (s.length > w) s.take(w) else if (s.length < w) s + (" " * (w - s.length)) else s
val fw = new java.io.FileWriter(java.nio.file.Paths.get(path).resolve("AdressMap.md").toString)
fw.append("| **Name** |**From**|**To** | **Description** |").append(NL)
.append("|:----------------|:------:|:------:|:-----------------------------------------|").append(NL)
for (off <- regs.keys.toList.sorted; reg = regs(off))
fw.append("| %s | 0x%04x | 0x%04x | %s |".format(
mksz(reg.name.getOrElse("N/A"), 15), off, off + axi.dataWidth / 8 - 1, reg.description
)).append(NL)
fw.flush()
fw.close
}
}
}
/**
* Axi4LiteRegisterFile bundle.
* @param cfg Configuration object.
* @param axi Implicit AXI configuration.
**/
class Axi4LiteRegisterFileIO(cfg: Axi4LiteRegisterFileConfiguration)(implicit axi: Configuration) extends Bundle {
val addrWidth: AddrWidth = AddrWidth(Seq(cfg.minAddrWidth:Int, axi.addrWidth:Int).max)
val saxi = Slave(axi)
/**
* Axi4LiteRegisterFile bundle.
* @param cfg [[Configuration]] object.
* @param axi Implicit AXI configuration.
**/
class IO(cfg: Configuration)(implicit axi: Axi4Lite.Configuration) extends Bundle {
val addrWidth: AddrWidth = AddrWidth(Seq(cfg.minAddrWidth:Int, axi.addrWidth:Int).max)
val saxi = Axi4Lite.Slave(axi)
}
}
/**
* Axi4LiteRegisterFile implements a register file:
* Writes currently take at least 3 cycles (addr -> data -> response), reads at least 2 (addr -> response).
* No strobe support, always read/write full register width.
* RegisterFile implements a AXI4Lite register file:
* Writes currently take at least 3 cycles (addr -> data -> response), reads at
* least 2 (addr -> response). No strobe support, always read/write full register
* width.
* @param cfg Configuration object.
* @param axi Implicit AXI configuration.
**/
class Axi4LiteRegisterFile(cfg: Axi4LiteRegisterFileConfiguration)(implicit axi: Configuration) extends Module {
class RegisterFile(cfg: RegisterFile.Configuration)
(implicit axi: Axi4Lite.Configuration,
logLevel: Logging.Level) extends Module with Logging {
/** HARDWARE **/
val io = IO(new Axi4LiteRegisterFileIO(cfg))
val io = IO(new RegisterFile.IO(cfg))
/** states: ready for address, transferring **/
val ready :: fetch :: transfer :: response :: Nil = Enum(4)
......@@ -91,10 +97,10 @@ class Axi4LiteRegisterFile(cfg: Axi4LiteRegisterFileConfiguration)(implicit axi:
// address receive state
when (r_state === ready && io.saxi.readAddr.valid) {
assert(io.saxi.readAddr.bits.prot.prot === 0.U, "Axi4LiteRegisterFile: read does not support PROT")
assert(io.saxi.readAddr.bits.prot.prot === 0.U, "RegisterFile: read does not support PROT")
r_addr := io.saxi.readAddr.bits.addr
r_state := fetch
printf("Axi4LiteRegisterFile: received read address 0x%x\n", io.saxi.readAddr.bits.addr)
info("received read address 0x${Hexadecimal(io.saxi.readAddr.bits.addr)}")
}
// wait one cycle for fetch
......@@ -103,7 +109,7 @@ class Axi4LiteRegisterFile(cfg: Axi4LiteRegisterFileConfiguration)(implicit axi:
// data transfer state
when (r_state === transfer && io.saxi.readData.ready) {
r_state := ready
printf("Axi4LiteRegisterFile: read 0x%x from address 0x%x\n", r_data, r_addr)
info("read 0x${Hexadecimal(r_data)} from address 0x${Hexadecimal(r_addr)}")
}
}
......@@ -130,10 +136,10 @@ class Axi4LiteRegisterFile(cfg: Axi4LiteRegisterFileConfiguration)(implicit axi:
// address receive state
when (w_state === ready) {
when (io.saxi.writeAddr.valid) {
assert(io.saxi.readAddr.bits.prot.prot === 0.U, "Axi4LiteRegisterFile: write does not support PROT")
assert(io.saxi.readAddr.bits.prot.prot === 0.U, "RegisterFile: write does not support PROT")
w_addr := io.saxi.writeAddr.bits.addr
w_state := transfer
printf("Axi4LiteRegisterFile: received write address 0x%x\n", io.saxi.writeAddr.bits.addr)
info("received write address 0x${Hexadecimal(io.saxi.writeAddr.bits.addr)}")
}
}
// data transfer state
......@@ -143,7 +149,7 @@ class Axi4LiteRegisterFile(cfg: Axi4LiteRegisterFileConfiguration)(implicit axi:
// assign data to reg
for (off <- cfg.regs.keys.toList.sorted) {
when (w_addr === off.U) {
printf("Axi4LiteRegisterFile: writing 0x%x to register with offset %d\n", w_data, off.U)
info("writing 0x${Hexadecimal(w_data)} to register with offset ${off.U}")
w_resp := Mux(cfg.regs(off).write(io.saxi.writeData.bits.data).B, Response.okay, Response.slverr)
}
}
......
package chisel.axiutils.registers
import Chisel.{Reg, UInt}
package chisel.axiutils.axi4lite
import Chisel.{Reg, UInt}
/**
* Abstract base class for control registers.
......
package chisel.axiutils
package object registers {
package object axi4lite {
/** Tuple-type for bit ranges. */
sealed case class BitRange(to: Int, from: Int) {
require (to >= from && from >= 0, "BitRange: invalid range (%d, %d)".format(to, from))
......
package chisel.axiutils
import chisel3._
import chisel3.util._
import chisel.axi._
/**
* AxiSlaveModelConfiguration configures an AxiSlaveModel 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 AxiSlaveModelConfiguration(val size: Int,
val readDelay: Int,
val writeDelay: Int)
(implicit axi: Axi4.Configuration) {
require (axi.dataWidth > 0 && axi.dataWidth <= 256, "dataWidth (%d) must be 0 < dataWidth <= 256".format(axi.dataWidth))
require (axi.idWidth.toInt == 1, "id width (%d) is not supported, use 1bit".format(axi.idWidth))
require (readDelay >= 0, "read delay (%d) must be >= 0".format(readDelay))
require (writeDelay >= 0, "write delay (%d) must be >= 0".format(writeDelay))
override def toString: String =
"addrWidth = %d, dataWidth = %d, idWidth = %d, size = %d, readDelay = %d, writeDelay = %d"
.format(axi.addrWidth:Int, axi.dataWidth:Int, axi.idWidth:Int, size, readDelay, writeDelay)
}
object AxiSlaveModelConfiguration {
/**
* Construct an AxiSlaveModelConfiguration. 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: 0).
* @param writeDelay simulated delay between write address handshake and data (default: 0).
**/
def apply(size: Option[Int] = None, readDelay: Int = 30, writeDelay: Int = 120)
(implicit axi: Axi4.Configuration) = {
val sz: Int = size.getOrElse(scala.math.pow(2, axi.addrWidth:Int).toInt / axi.dataWidth)
val aw: Int = Seq(axi.addrWidth:Int, log2Ceil(sz * axi.dataWidth / 8).toInt).min
new AxiSlaveModelConfiguration(size = sz, readDelay = readDelay, writeDelay = writeDelay)
}
}
package chisel.axiutils
package chisel.axiutils.axi4
import chisel3._
import chisel3.util._
import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
import chisel.axi._
import chisel.axiutils._
import org.scalatest.junit.JUnitSuite
import chisel.miscutils.DecoupledDataSource
import chisel.miscutils.{DecoupledDataSource, Logging}
import scala.math.{random, pow}
/**
* Composite test module:
* Uses FifoAxiAdapter to fill AxiSlaveModel; then reads data from
* AxiSlaveModel via AxiFifoAdapter.
* 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) extends Module {
(implicit axi: Axi4.Configuration, l: Logging.Level)
extends Module with Logging {
require (size.isEmpty || log2Ceil(size.get) <= axi.addrWidth,
"size (%d) elements cannot be addressed by %d address bits".format(size.get, axi.addrWidth:Int))
......@@ -24,21 +25,19 @@ 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
println ("Axi2AxiModule: address bits = %d, size = %d".format(aw, sz))
val cfg = AxiSlaveModelConfiguration()
cinfo ("Axi2AxiModule: address bits = %d, size = %d".format(aw, sz))
val cfg = SlaveModel.Configuration()
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 = n => UInt((random * pow(2, axi.dataWidth)).toInt),
//data = n => (n % pow(2, axi.dataWidth:Int).toInt).U,
data = data map (_.U),
repeat = false))
val fad = Module(new FifoAxiAdapter(fifoDepth = sz, burstSize = Some(fifoDepth)))
val saxi = Module(new AxiSlaveModel(cfg))
val saxi = Module(new SlaveModel(cfg))
val afa = Module(AxiFifoAdapter(fifoDepth = fifoDepth))
val base = 0.U(aw.W)
......@@ -48,7 +47,7 @@ class Axi2AxiModule(val fifoDepth: Int = 16, val size: Option[Int])
saxi.io.saxi.writeResp <> fad.io.maxi.writeResp
saxi.io.saxi.readAddr <> afa.io.maxi.readAddr
saxi.io.saxi.readData <> afa.io.maxi.readData
//afa.reset := dsrc.io.out.valid || fad.fifo.io.count > 0.U
// FIXME afa.reset := dsrc.io.out.valid || fad.fifo.io.count > 0.U
fad.io.base := base
afa.io.base := base
io.deq <> afa.io.deq
......@@ -61,7 +60,7 @@ class Axi2AxiModule(val fifoDepth: Int = 16, val size: Option[Int])
* Does NOT perform any timing checks, only correctness.
**/
class Axi2AxiTester(m: Axi2AxiModule)
(implicit axi: Axi4.Configuration) extends PeekPokeTester(m) {
(implicit axi: Axi4.Configuration, l: Logging.Level) extends PeekPokeTester(m) {
def toBinaryString(v: BigInt): String =
"b%%%ds".format(axi.dataWidth:Int).format(v.toString(2)).replace(' ', '0')
private val O = 10000
......@@ -93,6 +92,7 @@ class Axi2AxiTester(m: Axi2AxiModule)
/** Test suite using both AxiFifoAdapter and FifoAxiAdapter. **/
class Axi2AxiSuite extends ChiselFlatSpec {
import java.nio.file._
implicit val logLevel = chisel.miscutils.Logging.Level.Warn
def run(size: Int, fifoDepth: Int, addrWidth: Int, dataWidth: Int) {
implicit val axi = Axi4.Configuration(addrWidth = AddrWidth(addrWidth), dataWidth = DataWidth(dataWidth))
......
package chisel.axiutils
import chisel.miscutils.generators._
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
......@@ -8,10 +9,11 @@ import org.scalacheck._, org.scalacheck.Prop._
import org.scalatest.prop.Checkers
class AxiFifoAdapterModule1(val fifoDepth: Int, val blockSize: Int)
(implicit axi: Axi4.Configuration) extends Module {
(implicit axi: Axi4.Configuration,
logLevel: Logging.Level) extends Module {
val addrWidth = Seq(log2Ceil(axi.dataWidth * fifoDepth * blockSize / 8), 1).max
val cfg = AxiSlaveModelConfiguration(size = Some(Math.pow(2, addrWidth:Int).toInt))
val saxi = Module (new AxiSlaveModel(cfg))
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())
......@@ -95,6 +97,8 @@ class AxiFifoAdapterModule1Test(m: AxiFifoAdapterModule1)
}
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))
......
package chisel.axiutils
package chisel.axiutils.axi4
import chisel.axiutils._
import chisel.miscutils.Logging
import chisel3._
import chisel3.util._
import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
......@@ -10,15 +12,17 @@ import chisel.axi._
* @param n Number of parallel masters.
* @param axi Implicit AXI interface configuration.
**/
class AxiMuxReadTestModule(val n: Int)(implicit axi: Axi4.Configuration) extends Module {
class AxiMuxReadTestModule(val n: Int)
(implicit axi: Axi4.Configuration,
logLevel: Logging.Level) extends Module {
val io = IO(new Bundle {
val afa_deq_ready = Output(UInt(n.W))
val afa_deq_valid = Output(UInt(n.W))
val afa_deq_bits = Input(Vec(n, UInt(axi.dataWidth)))
})
val mux = Module(new AxiMux(n))
private val asmcfg = AxiSlaveModelConfiguration(size = Some(n * 128))
val saxi = Module(new AxiSlaveModel(asmcfg))
private val asmcfg = SlaveModel.Configuration(size = Some(n * 128))
val saxi = Module(new SlaveModel(asmcfg))
private val afacfg = AxiFifoAdapterConfiguration(fifoDepth = 8, burstSize = Some(4))
val afa = for (i <- 0 until n</