Commit 7395f54f authored by Jens Korinth's avatar Jens Korinth
Browse files

Minimize DecoupledDataSource

*  direct references of reset are discouraged
*  replaced all direct refs with RegInits, where appropriate
*  fixed overwrite bug in test outputs, each test writes in separate dir
parent 8e94f119
......@@ -3,56 +3,49 @@ import chisel3._
import chisel3.util._
object DecoupledDataSource {
/**
* Interface for DecoupledDataSource.
**/
/** Interface for DecoupledDataSource. */
class IO[T <: Data](gen: T) extends Bundle {
val out = Decoupled(gen.cloneType)
}
}
/**
* Data source providing fixed data via Decoupled interface.
* Provides the data given via Decoupled handshakes; if repeat
* is true, data is wrapped around.
* @param gen Type.
* @param size Total number of elements.
* @param data Function providing data for each index
* @param repeat If true, will always have data via wrap-around,
otherwise valid will go low after data was
consumed.
/** Data source providing fixed data via Decoupled interface.
* Provides the data given via Decoupled handshakes; if repeat
* is true, data is wrapped around.
* @param gen Type.
* @param size Total number of elements.
* @param data Function providing data for each index
* @param repeat If true, will always have data via wrap-around,
* otherwise valid will go low after data was
* consumed.
**/
class DecoupledDataSource[T <: Data](gen: T,
val size : Int,
val data: (Int) => T,
val repeat: Boolean = true)
(implicit l: Logging.Level)
extends Module with Logging {
(implicit l: Logging.Level) extends Module with Logging {
cinfo("size = %d, repeat = %s, addrWidth = %d".format(size,
if (repeat) "true" else "false", log2Ceil(if (repeat) size else size + 1)))
val ds = for (i <- 0 until size) yield data(i) // evaluate data to array
val io = IO(new DecoupledDataSource.IO(gen)) // interface
val i = Reg(UInt(log2Ceil(if (repeat) size else size + 1).W)) // index
val i = RegInit(UInt(log2Ceil(if (repeat) size else size + 1).W), 0.U) // index
val rom = Vec.tabulate(size)(n => ds(n)) // ROM with data
io.out.bits := rom(i) // current index data
io.out.valid := !reset && (i < size.U) // valid until exceeded
when (reset) {
i := 0.U
}
.otherwise {
when (io.out.ready && io.out.valid) {
val next = if (repeat) {
if (math.pow(2, log2Ceil(size)).toInt == size) {
i + 1.U
} else {
Mux((i + 1.U) < size.U, i + 1.U, 0.U)
}
} else {
Mux(i < size.U, i + 1.U, i)
}
info(p"i = $i -> $next, bits = 0x${Hexadecimal(io.out.bits.asUInt())}")
i := next
io.out.valid := i < size.U // valid until exceeded
when (io.out.ready && io.out.valid) {
val next = if (repeat) {
if (math.pow(2, log2Ceil(size)).toInt == size)
i + 1.U
else
Mux((i + 1.U) < size.U, i + 1.U, 0.U)
} else {
Mux(i < size.U, i + 1.U, i)
}
info(p"i = $i -> $next, bits = 0x${Hexadecimal(io.out.bits.asUInt())}")
i := next
}
}
......@@ -44,8 +44,9 @@ class DecoupledDataSourceSpec extends ChiselFlatSpec with Checkers {
check(forAll(bitWidthGen(64), dataSizeGen(1024), Arbitrary.arbitrary[Boolean]) { case (bw, sz, re) =>
println("Testing DecoupledDataSource with %d entries of width %d %s"
.format(bw:Int, sz:Int, if (re) "with repeat" else "without repeat"))
val dir = s"bw${bw:Int}sz${sz:Int}${if (re) "repeat" else "norepeat"}"
val data = 0 until sz map (i => scala.util.Random.nextInt().abs % math.pow(2, bw:Int).toInt)
Driver.execute(Array("--fint-write-vcd", "--target-dir", "test/DecoupledDataSource"),
Driver.execute(Array("--fint-write-vcd", "--target-dir", s"test/DecoupledDataSource/$dir"),
() => new DecoupledDataSource[UInt](0.U((bw:Int).W), sz, data map (_.U), re))
{ m => new OutputCheck(m, data) }
}, minSuccessful(25))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment