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

Bugfix in DataWidthConverter

* DWC only worked correctly at full speed
* delays caused lost nibbles, fixed now
* added secondary test harness to test against a slow receiver
parent 14b8a115
......@@ -44,11 +44,10 @@ class DataWidthConverter(
private def upsize() = {
val i = Reg(UInt(width = log2Up(ratio + 1)))
val d = Reg(UInt(width = outWidth))
val c = Reg(init = Bool(true))
io.inq.ready := !reset && (i =/= UInt(0) || io.deq.ready)
io.inq.ready := !reset && i =/= UInt(0)
io.deq.bits := d
io.deq.valid := !reset && (i === UInt(0) && c)
io.deq.valid := !reset && i === UInt(0)
when (reset) {
i := UInt(ratio)
......@@ -56,28 +55,28 @@ class DataWidthConverter(
}
.otherwise {
when (io.inq.ready && io.inq.valid) {
c := Bool(true)
if (littleEndian)
d := Cat(io.inq.bits, d) >> UInt(inWidth)
else
d := (d << UInt(inWidth)) | io.inq.bits
i := Mux(i === UInt(0), UInt(ratio - 1), i - UInt(1))
i := i - UInt(1)
}
when (io.deq.valid && io.deq.ready) {
i := UInt(ratio)
}
when (io.deq.valid && io.deq.ready) { c := Bool(false) }
}
}
private def downsize() = {
val i = Reg(UInt(width = log2Up(ratio)))
val i = Reg(UInt(width = log2Up(ratio + 1)))
val d = Reg(UInt(width = inWidth))
io.inq.ready := !reset && i === UInt(0)
io.inq.ready := !reset && (i === UInt(0) || (i === UInt(1) && io.deq.ready))
if (littleEndian)
io.deq.bits := d(outWidth - 1, 0)
else
io.deq.bits := d(inWidth - 1, inWidth - outWidth)
io.deq.valid := !reset && RegNext(i > UInt(0) || io.inq.valid)
io.deq.valid := !reset && i > UInt(0)
when (reset) {
i := UInt(0)
......@@ -91,9 +90,9 @@ class DataWidthConverter(
d := d << UInt(outWidth)
i := i - UInt(1)
}
when (i === UInt(0) && io.inq.valid) {
when (io.inq.ready && io.inq.valid) {
d := io.inq.bits
i := UInt(ratio - 1)
i := UInt(ratio)
}
}
}
......
......@@ -6,6 +6,53 @@ import org.junit.Assert._
import scala.math._
import java.nio.file.Paths
class SlowQueue(width: Int, delay: Int = 10) extends Module {
val io = new Bundle {
val enq = Decoupled(UInt(width = width)).flip
val deq = Decoupled(UInt(width = width))
}
val waiting :: ready :: Nil = Enum(UInt(), 2)
val state = Reg(init = ready)
val wr = Reg(UInt(width = log2Up(delay)))
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
}
.otherwise {
when (state === ready && io.enq.ready && io.deq.valid) {
state := waiting
wr := UInt(delay - 1)
}
when (state === waiting) {
wr := wr - UInt(1)
when (wr === UInt(0)) { state := ready }
}
}
}
class DataWidthConverterHarness(inWidth: Int, outWidth: Int, littleEndian: Boolean) extends Module {
val io = new Bundle
val dwc = Module(new DataWidthConverter(inWidth, outWidth, littleEndian))
val dsrc = Module(new DecoupledDataSource(UInt(width = inWidth),
Seq(Seq(pow(2, inWidth).toLong, dwc.ratio).max, 10000.toLong).min.toInt,
//n => UInt(n % pow(2, inWidth).toInt + 1, width = inWidth),
n => UInt((scala.math.random * pow(2, inWidth)).toLong, width = inWidth),
repeat = false))
val dwc2 = Module(new DataWidthConverter(outWidth, inWidth, littleEndian))
val slq = Module(new SlowQueue(outWidth, 7))
dwc.io.inq <> dsrc.io.out
slq.io.enq <> dwc.io.deq
dwc2.io.inq <> slq.io.deq
dwc2.io.deq.ready := Bool(true)
}
/**
* DataWidthConverterHarness: Correctness test harness.
* A DecoupledDataSource with random data is connected to a pair
......@@ -13,13 +60,13 @@ import java.nio.file.Paths
* must behave exactly like a delay on the input stream (where
* the length of the delay is 2 * in/out-width-ratio).
**/
class DataWidthConverterHarness(inWidth: Int, outWidth: Int, littleEndian: Boolean) extends Module {
class DataWidthConverterHarness2(inWidth: Int, outWidth: Int, littleEndian: Boolean) extends Module {
val io = new Bundle
val dwc = Module(new DataWidthConverter(inWidth, outWidth, littleEndian))
val dsrc = Module(new DecoupledDataSource(UInt(width = inWidth),
Seq(Seq(pow(2, inWidth).toInt, dwc.ratio).max, 10000).min,
Seq(Seq(pow(2, inWidth).toLong, dwc.ratio).max, 10000.toLong).min.toInt,
//n => UInt(n % pow(2, inWidth).toInt + 1, width = inWidth),
n => UInt((scala.math.random * pow(2, inWidth)).toInt, width = inWidth),
n => UInt((scala.math.random * pow(2, inWidth)).toLong, width = inWidth),
repeat = false))
val dwc2 = Module(new DataWidthConverter(outWidth, inWidth, littleEndian))
dwc.io.inq <> dsrc.io.out
......
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