Commit 11694b7d authored by Jens Korinth's avatar Jens Korinth
Browse files

Squashed 'miscutils/' changes from fa152fd..5041968

5041968 SlowQueue: remove direct reset references
bc2de4a Minimize SignalGenerator
91f6202 Minimize DecoupledDataSource
435a442 Minimize DataWidthConverter logic

git-subtree-dir: miscutils
git-subtree-split: 5041968ba66ec8c5329d7da6594b3f031437730d
parent dc850c61
......@@ -32,3 +32,5 @@ testForkedParallel in Test := false
scalacOptions ++= Seq("-language:implicitConversions", "-language:reflectiveCalls", "-deprecation", "-feature")
cleanFiles += baseDirectory.value / "test"
......@@ -47,58 +47,46 @@ class DataWidthConverter(val inWidth: Int,
upsize()
private def upsize() = {
val i = Reg(UInt(log2Ceil(ratio + 1).W))
val d = Reg(UInt(outWidth.W))
val i = RegInit(UInt(log2Ceil(ratio + 1).W), init = ratio.U)
val d = RegInit(UInt(outWidth.W), 0.U)
io.inq.ready := !reset && (i =/= 0.U || (io.inq.valid && io.deq.ready))
io.inq.ready := i =/= 0.U || (io.inq.valid && io.deq.ready)
io.deq.bits := d
io.deq.valid := !reset && i === 0.U
io.deq.valid := i === 0.U
when (reset) {
i := ratio.U
d := 0.U
when (io.inq.ready && io.inq.valid) {
if (littleEndian)
d := Cat(io.inq.bits, d) >> inWidth.U
else
d := (d << inWidth.U) | io.inq.bits
i := i - 1.U
}
.otherwise {
when (io.inq.ready && io.inq.valid) {
if (littleEndian)
d := Cat(io.inq.bits, d) >> inWidth.U
else
d := (d << inWidth.U) | io.inq.bits
i := i - 1.U
}
when (io.deq.valid && io.deq.ready) {
i := Mux(io.inq.valid, (ratio - 1).U, ratio.U)
}
when (io.deq.valid && io.deq.ready) {
i := Mux(io.inq.valid, (ratio - 1).U, ratio.U)
}
}
private def downsize() = {
val i = Reg(UInt(log2Ceil(ratio + 1).W))
val d = Reg(UInt(inWidth.W))
val i = RegInit(UInt(log2Ceil(ratio + 1).W), init = 0.U)
val d = RegInit(UInt(inWidth.W), init = 0.U)
io.inq.ready := !reset && (i === 0.U || (i === 1.U && io.deq.ready))
io.inq.ready := i === 0.U || (i === 1.U && io.deq.ready)
io.deq.valid := i > 0.U
if (littleEndian)
io.deq.bits := d(outWidth - 1, 0)
else
io.deq.bits := d(inWidth - 1, inWidth - outWidth)
io.deq.valid := !reset && i > 0.U
when (reset) {
i := 0.U
d := 0.U
when (i > 0.U && io.deq.ready) {
if (littleEndian)
d := d >> outWidth.U
else
d := d << outWidth.U
i := i - 1.U
}
.otherwise {
when (i > 0.U && io.deq.ready) {
if (littleEndian)
d := d >> outWidth.U
else
d := d << outWidth.U
i := i - 1.U
}
when (io.inq.ready && io.inq.valid) {
d := io.inq.bits
i := ratio.U
}
when (io.inq.ready && io.inq.valid) {
d := io.inq.bits
i := ratio.U
}
}
}
......
......@@ -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
}
}
......@@ -31,29 +31,22 @@ class SignalGenerator(val signals: SignalGenerator.Waveform,
val io = IO(new SignalGenerator.IO)
val cnts_rom = Vec(signals map (n => (n.periods - 1).U))
val vals_rom = Vec(signals map (n => (n.value).B))
val cnt = Reg(UInt(log2Ceil(signals.max.periods).W))
val curr_idx = Reg(UInt(log2Ceil(signals.length).W))
val vreg = Reg(Bool())
val cnt = RegInit(UInt(log2Ceil(signals.max.periods).W), init = cnts_rom(0))
val curr_idx = RegInit(UInt(log2Ceil(signals.length).W), init = 0.U)
val vreg = RegInit(Bool(), init = vals_rom(0))
io.v := vreg
when (reset) {
curr_idx := 0.U
cnt := cnts_rom(0)
vreg := vals_rom(0)
}
.otherwise {
vreg := vals_rom(curr_idx)
// trigger on either clock or pos input edge
when (if (useInputAsClock) io.in && !RegNext(io.in) else true.B) {
when (cnt === 0.U) {
val next_idx = Mux(curr_idx < (signals.length - 1).U, curr_idx + 1.U, 0.U)
curr_idx := next_idx
cnt := cnts_rom(next_idx)
}
.otherwise {
cnt := cnt - 1.U
}
vreg := vals_rom(curr_idx)
// trigger on either clock or pos input edge
when (if (useInputAsClock) io.in && !RegNext(io.in) else true.B) {
when (cnt === 0.U) {
val next_idx = Mux(curr_idx < (signals.length - 1).U, curr_idx + 1.U, 0.U)
curr_idx := next_idx
cnt := cnts_rom(next_idx)
}
.otherwise {
cnt := cnt - 1.U
}
}
}
......@@ -13,24 +13,19 @@ class SlowQueue(width: Int, val delay: Int = 10) extends Module {
val waiting :: ready :: Nil = Enum(2)
val state = RegInit(ready)
val wr = Reg(UInt(log2Ceil(delay).W))
val wr = RegInit(UInt(log2Ceil(delay).W), io.dly)
io.deq.bits := io.enq.bits
io.enq.ready := io.deq.ready && state === ready
io.deq.valid := io.enq.valid && state === ready
when (reset) {
state := ready
when (state === ready && io.enq.ready && io.deq.valid) {
state := waiting
wr := io.dly
}
.otherwise {
when (state === ready && io.enq.ready && io.deq.valid) {
state := waiting
wr := io.dly
}
when (state === waiting) {
wr := wr - 1.U
when (wr === 0.U) { state := ready }
}
when (state === waiting) {
wr := wr - 1.U
when (wr === 0.U) { state := ready }
}
}
......@@ -15,7 +15,9 @@ class DataWidthConverterSpec extends ChiselFlatSpec with Checkers {
forAll(conversionWidthGen(inW)) { outW =>
println("Testing bitwidth conversion from %d bits -> %d bits (%s) with %d delay"
.format(inW:Int, outW:Int, if (littleEndian) "little-endian" else "big-endian", delay:Int))
Driver.execute(Array("--fint-write-vcd", "--target-dir", "test/DataWidthConverter"),
val end = if (littleEndian) "littleEndian" else "bigEndian"
val dir = s"in${inW:Int}out${outW:Int}${end}delay${delay:Int}"
Driver.execute(Array("--fint-write-vcd", "--target-dir", s"test/DataWidthConverter/$dir"),
() => new CorrectnessHarness(inW, outW, littleEndian, 1))
{ m => new CorrectnessTester(m) }
}
......@@ -26,7 +28,9 @@ class DataWidthConverterSpec extends ChiselFlatSpec with Checkers {
forAll(conversionWidthGen(inW)) { outW =>
println("Testing bitwidth conversion from %d bits -> %d bits (%s)"
.format(inW:Int, outW:Int, if (littleEndian) "little-endian" else "big-endian"))
Driver.execute(Array("--fint-write-vcd", "--target-dir", "test/DataWidthConverter"),
val end = if (littleEndian) "littleEndian" else "bigEndian"
val dir = s"in${inW:Int}out${outW:Int}${end}delay0"
Driver.execute(Array("--fint-write-vcd", "--target-dir", s"test/DataWidthConverter/$dir"),
() => new MinimalDelayHarness(inW, outW, littleEndian))
{ m => new MinimalDelayTester(m) }
}
......
......@@ -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))
......
......@@ -10,9 +10,9 @@ import scala.util.Random
/** Connects a random clock signal generator to the main signal generator to test
* external clock port facilities.
*/
**/
class SignalGeneratorWithClockInput(val signals: Waveform) extends Module {
val io = IO(new Bundle { val v = Output(Bool()); val clk = Output(Bool()) })
val io = IO(new Bundle { val v = Output(Bool()); val clk = Output(Bool()) })
val clw = 0 to signals.length * 2 map (i => Signal(i % 2 == 0, 2 + Random.nextInt().abs % 10))
val clk = Module(new SignalGenerator(clw))
val sgn = Module(new SignalGenerator(signals, true))
......
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