summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/QueueFlushSpec.scala
diff options
context:
space:
mode:
authorAditya Naik2023-11-23 03:11:56 -0800
committerAditya Naik2023-11-23 03:11:56 -0800
commitaf415532cf160e63e971ceb301833b8433c18a50 (patch)
tree1fef70139846f57298c8e24a590490a74249f7dd /src/test/scala/chiselTests/QueueFlushSpec.scala
parent8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff)
cleanup
Diffstat (limited to 'src/test/scala/chiselTests/QueueFlushSpec.scala')
-rw-r--r--src/test/scala/chiselTests/QueueFlushSpec.scala294
1 files changed, 0 insertions, 294 deletions
diff --git a/src/test/scala/chiselTests/QueueFlushSpec.scala b/src/test/scala/chiselTests/QueueFlushSpec.scala
deleted file mode 100644
index d70f9605..00000000
--- a/src/test/scala/chiselTests/QueueFlushSpec.scala
+++ /dev/null
@@ -1,294 +0,0 @@
-package chiselTests
-
-import org.scalacheck._
-
-import chisel3._
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.util._
-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)
-
-/** 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 {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, hasFlush = true))
- val elems = VecInit(elements.map(_.U))
- val inCnt = Counter(elements.length + 1)
- val outCnt = RegInit(0.U(log2Ceil(elements.length).W))
- val currQCnt = RegInit(0.U(log2Ceil(5).W))
-
- val flush: Bool = WireInit(false.B)
- val flushRegister = RegNext(flush, init = false.B)
- q.io.flush.get := flush
- q.io.enq.valid := (inCnt.value < elements.length.U)
- q.io.deq.ready := LFSR(16)(tap)
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- currQCnt := currQCnt + 1.U //counts how many items have been enqueued
- }
- when(q.io.deq.fire) {
- assert(flushRegister === false.B) //check queue isn't flushed (can't dequeue an empty queue)
- }
- when(flushRegister) { //Internal signal maybe_full is a register so some signals update on the next cycle
- //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"
- )
- }
- 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
-
- 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) {
- currQCnt := Mux(q.io.enq.fire, currQCnt, (currQCnt - 1.U))
- }
- }
- when(flush) {
- assert(currQCnt === 0.U || q.io.deq.valid)
- outCnt := outCnt + Mux(q.io.enq.fire, (currQCnt + 1.U), currQCnt)
- currQCnt := 0.U //resets the number of items currently inside queue
- }
-}
-
-/** 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) {
- 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
- q.io.enq.valid := (inCnt.value < elements.length.U) && !flush
-
- when(q.io.deq.fire) {
- assert(elems(outCnt) === q.io.deq.bits)
- outCnt := outCnt + 1.U
- }
-}
-
-/** 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) {
- 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
- cycleCounter.inc() //counts every cycle
-
- when(q.io.deq.fire) {
- //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()
- }
-}
-
-/** 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) {
-
- //testing a flush when queue is full
- flush := (currQCnt === queueDepth.U)
-
- 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) {
- currQCnt := currQCnt - 1.U
- }
- }
- when(flush) {
- outCnt := outCnt + currQCnt
- currQCnt := 0.U //resets the number of items currently inside queue
- assert(currQCnt === 0.U || q.io.deq.valid)
- }
-}
-
-/** 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) {
- //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
- q.io.enq.valid := !flushRegister
- q.io.deq.ready := flush
-
- 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)
- assert(currQCnt > 0.U)
- }
- 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
- 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)
- }
-
-}
-
-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) {
- assertTesterPasses {
- new ThingsPassThroughFlushQueueTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue should flush when requested") {
- 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) {
- assertTesterPasses {
- new QueueGetsFlushedTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue flush when queue is empty") {
- 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) {
- assertTesterPasses {
- new EmptyFlushEdgecaseTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Test queue can enqueue during a flush") {
- 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) {
- assertTesterPasses {
- new EnqueueEmptyFlushEdgecaseTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue flush when queue is full") {
- 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) {
- assertTesterPasses {
- new FullQueueFlushEdgecaseTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- 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(
- new DequeueFullQueueEdgecaseTester(se._2, depth, se._1, tap, isSync),
- annotations = Seq(WriteVcdAnnotation)
- )
- }
- }
- }
-}