diff options
Diffstat (limited to 'src/test/scala/chiselTests/QueueFlushSpec.scala')
| -rw-r--r-- | src/test/scala/chiselTests/QueueFlushSpec.scala | 91 |
1 files changed, 63 insertions, 28 deletions
diff --git a/src/test/scala/chiselTests/QueueFlushSpec.scala b/src/test/scala/chiselTests/QueueFlushSpec.scala index 9e0c6bb4..d70f9605 100644 --- a/src/test/scala/chiselTests/QueueFlushSpec.scala +++ b/src/test/scala/chiselTests/QueueFlushSpec.scala @@ -9,24 +9,36 @@ import chisel3.util.random.LFSR import treadle.WriteVcdAnnotation /** Test elements can be enqueued and dequeued when flush is tied to false - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class ThingsPassThroughFlushQueueTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends ThingsPassThroughTester(elements, queueDepth, bitWidth, tap, useSyncReadMem, hasFlush = true) +class ThingsPassThroughFlushQueueTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends ThingsPassThroughTester(elements, queueDepth, bitWidth, tap, useSyncReadMem, hasFlush = true) /** Generic flush queue tester base class - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -abstract class FlushQueueTesterBase(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { +abstract class FlushQueueTesterBase( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth, hasFlush = true)) val elems = VecInit(elements.map(_.U)) val inCnt = Counter(elements.length + 1) @@ -51,31 +63,35 @@ abstract class FlushQueueTesterBase(elements: Seq[Int], queueDepth: Int, bitWidt //check that queue gets flushed when queue is full assert(q.io.count === 0.U) assert(!q.io.deq.valid, "Expected to not be able to dequeue when flush is asserted the previous cycle") - assert(q.io.enq.ready, "Expected enqueue to be ready when flush was asserted the previous cycle because queue should be empty") - } + assert( + q.io.enq.ready, + "Expected enqueue to be ready when flush was asserted the previous cycle because queue should be empty" + ) + } when(inCnt.value === elements.length.U) { //stop when all entries are enqueued stop() } } /** Test queue can flush at random times - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { - flush := LFSR(16)((tap + 3) % 16) //testing a flush when flush is called randomly - val halfCnt = (queueDepth + 1)/2 +class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { + flush := LFSR(16)((tap + 3) % 16) //testing a flush when flush is called randomly + val halfCnt = (queueDepth + 1) / 2 when(q.io.deq.fire) { //ensure that what comes out is what comes in assert(currQCnt <= queueDepth.U) assert(elems(outCnt) === q.io.deq.bits) outCnt := outCnt + 1.U - when (currQCnt > 0.U) { + when(currQCnt > 0.U) { currQCnt := Mux(q.io.enq.fire, currQCnt, (currQCnt - 1.U)) } } @@ -87,19 +103,20 @@ class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, } /** Test queue can flush when empty - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class EmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class EmptyFlushEdgecaseTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { val cycleCounter = Counter(elements.length + 1) cycleCounter.inc() //counts every cycle //testing a flush when queue is empty - flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued + flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued q.io.enq.valid := (inCnt.value < elements.length.U) && !flush when(q.io.deq.fire) { @@ -109,23 +126,29 @@ class EmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: I } /** Test queue can enqueue during a flush - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class EnqueueEmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class EnqueueEmptyFlushEdgecaseTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { val cycleCounter = Counter(elements.length + 1) val outCounter = Counter(elements.length + 1) //testing an enqueue during a flush - flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued + flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued cycleCounter.inc() //counts every cycle when(q.io.deq.fire) { - //flush and enqueue were both active on the first cycle, + //flush and enqueue were both active on the first cycle, //so that element is flushed immediately which makes outCnt off by one assert(elems(outCounter.value + 1.U) === q.io.deq.bits) //ensure that what comes out is what comes in outCounter.inc() @@ -133,14 +156,20 @@ class EnqueueEmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitW } /** Test queue can flush when full - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class FullQueueFlushEdgecaseTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { //testing a flush when queue is full flush := (currQCnt === queueDepth.U) @@ -150,7 +179,7 @@ class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidt assert(currQCnt <= queueDepth.U) assert(elems(outCnt) === q.io.deq.bits) outCnt := outCnt + 1.U - when (currQCnt > 0.U) { + when(currQCnt > 0.U) { currQCnt := currQCnt - 1.U } } @@ -162,18 +191,24 @@ class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidt } /** Test queue can dequeue on the same cycle as a flush - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class DequeueFullQueueEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class DequeueFullQueueEdgecaseTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { //Queue should be able to dequeue when queue is not empty and flush is high //testing a flush when dequeue is called - flush := currQCnt === (queueDepth/2).U + flush := currQCnt === (queueDepth / 2).U q.io.enq.valid := !flushRegister q.io.deq.ready := flush @@ -185,14 +220,14 @@ class DequeueFullQueueEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWi } when(flush) { //The outcount register is one count behind because the dequeue happens at the same time as the flush - outCnt := outCnt + currQCnt + 1.U + outCnt := outCnt + currQCnt + 1.U currQCnt := 0.U //resets the number of items currently inside queue assert(currQCnt === 0.U || q.io.deq.valid) } when(flushRegister) { //check that queue gets flushed when queue is full assert(q.io.deq.fire === false.B) - } + } } @@ -200,7 +235,7 @@ class QueueFlushSpec extends ChiselPropSpec { // Disable shrinking on error. implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) - + property("Queue should have things pass through") { forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) => whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) { @@ -249,7 +284,7 @@ class QueueFlushSpec extends ChiselPropSpec { property("Queue should be able to dequeue when flush is high") { forAll(Gen.choose(3, 5), safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) => whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) { - assertTesterPasses ( + assertTesterPasses( new DequeueFullQueueEdgecaseTester(se._2, depth, se._1, tap, isSync), annotations = Seq(WriteVcdAnnotation) ) |
