From 52b4e4540983909c248f115dc59caf0be4ed5775 Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Mon, 6 May 2024 16:52:52 +0200 Subject: [PATCH 1/8] Update dependencies. --- build.sbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index a5889c7..5c977ef 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -val chiselVersion = "5.1.0" +val chiselVersion = "6.3.0" ThisBuild / scalaVersion := "2.13.12" @@ -25,7 +25,7 @@ lazy val library: Project = (project in file("library")) commonSettings, name := "Tydi-Chisel", description := "Tydi-Chisel is an implementation of Tydi concepts in the Chisel HDL.", - libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "5.0.2" % Test + libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "6.0.0" % Test ) // .dependsOn(testingTools % "test->test") @@ -34,7 +34,7 @@ lazy val testingTools: Project = (project in file("testing")) commonSettings, name := "Tydi-Chisel-Test", description := "This package contains the testing tools for Tydi-Chisel", - libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "5.0.2" + libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "6.0.0" ) .dependsOn(library % "compile->compile") // Make testingTools project depend on the library project From 88bc43af55d7903640e3d3e5299ca4dfaa07efae Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Mon, 6 May 2024 17:13:36 +0200 Subject: [PATCH 2/8] Update test driver. Attempt to mimic the chiseltest commit. https://github.com/ucb-bar/chiseltest/commit/6457e1a372e776ae4c159e5df86b5123b514c0a1#diff-55b4dda27855b658cc149b55f650789b6cc409b6bc1f437b0f36eb37711d45a8 --- .../tydi_chisel_test/TydiTesting.scala | 136 ++++++++---------- 1 file changed, 56 insertions(+), 80 deletions(-) diff --git a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala index acb99fa..0c07870 100644 --- a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala +++ b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala @@ -20,7 +20,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel // Source (enqueue) functions // def initSource(): this.type = { - x.valid.poke(false.B) + x.valid.poke(false) x.stai.poke(0.U) x.endi.poke((x.n - 1).U) x.strb.poke(((1 << x.n) - 1).U(x.n.W)) // Set strobe to all 1's @@ -29,19 +29,6 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel this } - def setSourceClock(clock: Clock): this.type = { - ClockResolutionUtils.setClock(TydiStreamDriver.decoupledSourceKey, x, clock) - this - } - - protected def getSourceClock: Clock = { - ClockResolutionUtils.getClock( - TydiStreamDriver.decoupledSourceKey, - x, - x.ready.getSourceClock() - ) // TODO: validate against bits/valid sink clocks - } - def elLit(elems: (Tel => (Data, Data))*): Tel = { // Must use datatype instead of just .data or .el because Lit does not accept hardware types. // Use splat operator to propagate repeated parameters @@ -62,8 +49,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None - ): Unit = timescope { - // TODO: check for init + ): Unit = { x.el.poke(data) if (last.isDefined) { val lastLit = Vec(x.n, UInt(x.d.W)).Lit(0 -> last.get) @@ -78,12 +64,13 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel if (endi.isDefined) { x.endi.poke(endi.get) } - x.valid.poke(true.B) + x.valid.poke(true) fork .withRegion(Monitor) { - x.ready.expect(true.B) + x.ready.expect(true) } - .joinAndStep(getSourceClock) + .joinAndStep() + x.valid.poke(false) } def enqueueNow( @@ -92,8 +79,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None - ): Unit = timescope { - // TODO: check for init + ): Unit = { x.data.pokePartial(data) if (last.isDefined) { x.last.pokePartial(last.get) @@ -107,12 +93,13 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel if (endi.isDefined) { x.endi.poke(endi.get) } - x.valid.poke(true.B) + x.valid.poke(true) fork .withRegion(Monitor) { - x.ready.expect(true.B) + x.ready.expect(true) } - .joinAndStep(getSourceClock) + .joinAndStep() + x.valid.poke(false) } /** Send an empty transfer (no valid data lanes). Unless overridden, a strobe of 0's is sent. */ @@ -121,8 +108,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None - ): Unit = timescope { - // TODO: check for init + ): Unit = { if (last.isDefined) { x.last.pokePartial(last.get) } /* else { @@ -141,38 +127,39 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel if (endi.isDefined) { x.endi.poke(endi.get) } - x.valid.poke(true.B) + x.valid.poke(true) fork .withRegion(Monitor) { - x.ready.expect(true.B) + x.ready.expect(true) } - .joinAndStep(getSourceClock) + .joinAndStep() + x.valid.poke(true) } - def enqueueElNow(elems: (Tel => (Data, Data))*): Unit = timescope { + def enqueueElNow(elems: (Tel => (Data, Data))*): Unit = { val litValue = elLit(elems: _*) // Use splat operator to propagate repeated parameters enqueueElNow(litValue) } - def enqueue(data: Tel): Unit = timescope { - // TODO: check for init + def enqueue(data: Tel): Unit = { x.el.poke(data) - x.valid.poke(true.B) + x.valid.poke(true) fork .withRegion(Monitor) { - while (x.ready.peek().litToBoolean == false) { - getSourceClock.step(1) + while (!x.ready.peekBoolean()) { + step(1) } } - .joinAndStep(getSourceClock) + .joinAndStep() + x.valid.poke(true) } - def enqueue(elems: (Tel => (Data, Data))*): Unit = timescope { + def enqueue(elems: (Tel => (Data, Data))*): Unit = { val litValue = elLit(elems: _*) // Use splat operator to propagate repeated parameters enqueue(litValue) } - def enqueueSeq(data: Seq[Tel]): Unit = timescope { + def enqueueSeq(data: Seq[Tel]): Unit = { for (elt <- data) { enqueue(elt) } @@ -181,43 +168,37 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel // Sink (dequeue) functions // def initSink(): this.type = { - x.ready.poke(false.B) + x.ready.poke(false) this } - def setSinkClock(clock: Clock): this.type = { - ClockResolutionUtils.setClock(TydiStreamDriver.decoupledSinkKey, x, clock) - this - } - - protected def getSinkClock: Clock = { - ClockResolutionUtils.getClock( - TydiStreamDriver.decoupledSinkKey, - x, - x.valid.getSourceClock() - ) // TODO: validate against bits/valid sink clocks - } + @deprecated("You no longer need to set the clock explicitly.", since = "6.0.x") + protected val decoupledSourceKey = new Object() + def setSourceClock(clock: Clock): this.type = this + protected val decoupledSinkKey = new Object() + @deprecated("You no longer need to set the clock explicitly.", since = "6.0.x") + def setSinkClock(clock: Clock): this.type = this // NOTE: this doesn't happen in the Monitor phase, unlike public functions def waitForValid(): Unit = { while (!x.valid.peek().litToBoolean) { - getSinkClock.step(1) + step(1) } } - def expectDequeue(data: Tel): Unit = timescope { - // TODO: check for init - x.ready.poke(true.B) + def expectDequeue(data: Tel): Unit = { + x.ready.poke(true) fork .withRegion(Monitor) { waitForValid() - x.valid.expect(true.B) + x.valid.expect(true) x.el.expect(data) } - .joinAndStep(getSinkClock) + .joinAndStep() + x.ready.poke(false) } - def expectDequeue(elems: (Tel => (Data, Data))*): Unit = timescope { + def expectDequeue(elems: (Tel => (Data, Data))*): Unit = { val litValue = elLit(elems: _*) // Use splat operator to propagate repeated parameters expectDequeue(litValue) } @@ -228,12 +209,11 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None - ): Unit = timescope { - // TODO: check for init - x.ready.poke(true.B) + ): Unit = { + x.ready.poke(true) fork .withRegion(Monitor) { - x.valid.expect(true.B) + x.valid.expect(true) x.el.expect(data) if (last.isDefined) { x.last.expect(last.get) @@ -248,7 +228,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.strb.expect(strb.get) } } - .joinAndStep(getSinkClock) + .joinAndStep() + x.ready.poke(false) } /** Expect an empty transfer (no valid data lanes). Unless overridden, a strobe of 0's is expected. */ @@ -257,12 +238,11 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None - ): Unit = timescope { - // TODO: check for init - x.ready.poke(true.B) + ): Unit = { + x.ready.poke(true) fork .withRegion(Monitor) { - x.valid.expect(true.B) + x.valid.expect(true) if (strb.isDefined) { x.strb.expect(strb.get) } else { @@ -278,15 +258,16 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.endi.expect(endi.get) } } - .joinAndStep(getSinkClock) + .joinAndStep() + x.ready.poke(false) } - def expectDequeueNow(elems: (Tel => (Data, Data))*): Unit = timescope { + def expectDequeueNow(elems: (Tel => (Data, Data))*): Unit = { val litValue = elLit(elems: _*) // Use splat operator to propagate repeated parameters expectDequeueNow(litValue) } - def expectDequeueSeq(data: Seq[Tel]): Unit = timescope { + def expectDequeueSeq(data: Seq[Tel]): Unit = { for (elt <- data) { expectDequeue(elt) } @@ -294,14 +275,14 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel def expectPeek(data: Tel): Unit = { fork.withRegion(Monitor) { - x.valid.expect(true.B) + x.valid.expect(true) x.el.expect(data) } } def expectInvalid(): Unit = { fork.withRegion(Monitor) { - x.valid.expect(false.B) + x.valid.expect(false) } } @@ -316,14 +297,14 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel val streamAntiDir = if (x.r) out else in try - stringBuilder.append(s"State of \"${x.instanceName}\" $streamDir @ clk-step ${getSinkClock.getStepCount}:\n") + stringBuilder.append(s"State of \"${x.instanceName}\" $streamDir @ clk-step ${x.getSourceClock().getStepCount}:\n") catch { case e: ClockResolutionException => stringBuilder.append(s"State of \"${x.instanceName}\" $streamDir (unable to get clock):\n") } // Valid and ready signals - stringBuilder.append(s"valid $streamDir: ${logicSymbol(x.valid.peek().litToBoolean)}\t\t\t") - stringBuilder.append(s"ready $streamAntiDir: ${logicSymbol(x.ready.peek().litToBoolean)}\n") + stringBuilder.append(s"valid $streamDir: ${logicSymbol(x.valid.peekBoolean())}\t\t\t") + stringBuilder.append(s"ready $streamAntiDir: ${logicSymbol(x.ready.peekBoolean())}\n") // Stai and endi signals stringBuilder.append(s"stai ≥: ${x.stai.peek().litValue}\t\t\t") stringBuilder.append(s"endi ≤: ${x.endi.peek().litValue}\n") @@ -368,11 +349,6 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } } -object TydiStreamDriver { - protected val decoupledSourceKey = new Object() - protected val decoupledSinkKey = new Object() -} - object printUtils { def printVecBinary[T <: Data](vec: Vec[T]): String = { vec.map(v => binaryFromData(v)).mkString(", ") From fc7c271ee3973334a03d93afe9003f3bb5e15c47 Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Wed, 8 May 2024 13:07:39 +0200 Subject: [PATCH 3/8] Remove timescopes from complexity converter test. Add run argument to driver functions for printing purposes. --- .../tydi_chisel_test/TydiTesting.scala | 20 ++- .../utils/ComplexityConverterTest.scala | 134 ++++++++---------- 2 files changed, 75 insertions(+), 79 deletions(-) diff --git a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala index 0c07870..c248561 100644 --- a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala +++ b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala @@ -48,7 +48,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel last: Option[UInt] = None, strb: Option[UInt] = None, stai: Option[UInt] = None, - endi: Option[UInt] = None + endi: Option[UInt] = None, + run: => Unit = {} ): Unit = { x.el.poke(data) if (last.isDefined) { @@ -65,6 +66,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.endi.poke(endi.get) } x.valid.poke(true) + run fork .withRegion(Monitor) { x.ready.expect(true) @@ -78,7 +80,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel last: Option[Vec[UInt]] = None, strb: Option[UInt] = None, stai: Option[UInt] = None, - endi: Option[UInt] = None + endi: Option[UInt] = None, + run: => Unit = {} ): Unit = { x.data.pokePartial(data) if (last.isDefined) { @@ -94,6 +97,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.endi.poke(endi.get) } x.valid.poke(true) + run fork .withRegion(Monitor) { x.ready.expect(true) @@ -107,7 +111,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel last: Option[Vec[UInt]] = None, strb: Option[UInt] = None, stai: Option[UInt] = None, - endi: Option[UInt] = None + endi: Option[UInt] = None, + run: => Unit = {} ): Unit = { if (last.isDefined) { x.last.pokePartial(last.get) @@ -128,6 +133,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.endi.poke(endi.get) } x.valid.poke(true) + run fork .withRegion(Monitor) { x.ready.expect(true) @@ -208,12 +214,14 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel last: Option[Vec[UInt]] = None, strb: Option[UInt] = None, stai: Option[UInt] = None, - endi: Option[UInt] = None + endi: Option[UInt] = None, + run: => Unit = {} ): Unit = { x.ready.poke(true) fork .withRegion(Monitor) { x.valid.expect(true) + run x.el.expect(data) if (last.isDefined) { x.last.expect(last.get) @@ -237,12 +245,14 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel last: Option[Vec[UInt]] = None, strb: Option[UInt] = None, stai: Option[UInt] = None, - endi: Option[UInt] = None + endi: Option[UInt] = None, + run: => Unit = {} ): Unit = { x.ready.poke(true) fork .withRegion(Monitor) { x.valid.expect(true) + run if (strb.isDefined) { x.strb.expect(strb.get) } else { diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala index 57c9cc6..2c2e025 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala @@ -327,76 +327,71 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { { // Send some data in // shei - timescope({ - c.in.valid.poke(true) - c.in.data.pokePartial(t1) - c.in.strb.poke(bRev("1111")) - c.in.last.poke(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b00".U)) - println("\n-- Transfer in 1") - printInputState(c) - c.clock.step(1) - println(s"All data: ${c.exposed_storedData.peek().asString}") - }) - - timescope({ - c.clock.step(1) - }) + c.in.enqueueNow(t1, + Option(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b00".U)), + Option(bRev("1111")), + run = { + println("\n-- Transfer in 1") + printInputState(c) + } + ) + println(s"All data: ${c.exposed_storedData.peek().asString}") + + c.clock.step(1) // s_a_ - timescope({ - c.in.valid.poke(true) - c.in.data.pokePartial(t3) - c.in.strb.poke(bRev("1010")) - c.in.last.poke(Vec.Lit("b01".U(2.W), "b00".U, "b01".U, "b00".U)) - println("\n-- Transfer in 3") - printInputState(c) - c.clock.step(1) - println(s"All data: ${c.exposed_storedData.peek().asString}") - }) + c.in.enqueueNow(t3, + Option(Vec.Lit("b01".U(2.W), "b00".U, "b01".U, "b00".U)), + Option(bRev("1010")), + run = { + println("\n-- Transfer in 3") + printInputState(c) + } + ) + println(s"All data: ${c.exposed_storedData.peek().asString}") // d_ol - timescope({ - c.in.valid.poke(true) - c.in.data.pokePartial(t4) - c.in.strb.poke(bRev("1011")) - c.in.last.poke(Vec.Lit("b00".U(2.W), "b00".U, "b00".U, "b00".U)) - println("\n-- Transfer in 4") - printInputState(c) - c.clock.step(1) - println(s"All data: ${c.exposed_storedData.peek().asString}") - }) + c.in.enqueueNow(t4, + Option(Vec.Lit("b00".U(2.W), "b00".U, "b00".U, "b00".U)), + Option(bRev("1011")), + run = { + println("\n-- Transfer in 4") + printInputState(c) + } + ) + println(s"All data: ${c.exposed_storedData.peek().asString}") // ph__ - timescope({ - c.in.valid.poke(true) - c.in.data.pokePartial(t5) - c.in.strb.poke(bRev("1100")) - c.in.last.poke(Vec.Lit("b00".U(2.W), "b00".U, "b00".U, "b00".U)) - println("\n-- Transfer in 5") - printInputState(c) - c.clock.step(1) - println(s"All data: ${c.exposed_storedData.peek().asString}") - }) + c.in.enqueueNow(t5, + Option(Vec.Lit("b00".U(2.W), "b00".U, "b00".U, "b00".U)), + Option(bRev("1100")), + run = { + println("\n-- Transfer in 5") + printInputState(c) + } + ) + println(s"All data: ${c.exposed_storedData.peek().asString}") // __in - timescope({ - c.in.valid.poke(true) - c.in.data.pokePartial(t6) - c.in.strb.poke(bRev("0011")) - println("\n-- Transfer in 6") - printInputState(c) - c.clock.step(1) - println(s"All data: ${c.exposed_storedData.peek().asString}") - }) + c.in.enqueueNow(t6, + None, + Option(bRev("0011")), + run = { + println("\n-- Transfer in 6") + printInputState(c) + } + ) + println(s"All data: ${c.exposed_storedData.peek().asString}") // close off - timescope({ - c.in.valid.poke(true) - c.in.last.poke(Vec.Lit("b11".U(2.W), "b00".U, "b00".U, "b00".U)) - println("\n-- Transfer in 7") - printInputState(c) - c.clock.step(1) - }) + c.in.enqueueEmptyNow( + Option(Vec.Lit("b11".U(2.W), "b00".U, "b00".U, "b00".U)), + Option(bRev("0000")), + run = { + println("\n-- Transfer in 7") + printInputState(c) + } + ) println(s"All data: ${c.exposed_storedData.peek().asString}") println(s"All lasts: ${printVecBinary(c.exposed_storedLasts.peek())}") @@ -510,21 +505,12 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { println(s"All data: ${c.exposed_storedData.peek().asString}") // ce____ -// c.in.enqueueNow(t4, -// last = Some(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b10".U, "b11".U, "b10".U)), -// strb = Some(bRev("110000"))) - - timescope({ - c.in.valid.poke(true) - c.in.data.pokePartial(t4) - c.in.last.poke(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b10".U, "b11".U, "b10".U)) - c.in.strb.poke(bRev("110000")) - print(c.in.printState(charRenderer)) - c.clock.step(1) - }) - println("\n-- Transfer in 4") - println(s"All data: ${c.exposed_storedData.peek().asString}") + c.in.enqueueNow(t4, + last = Some(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b10".U, "b11".U, "b10".U)), + strb = Some(bRev("110000"))) + print(c.in.printState(charRenderer)) + println("\n-- Transfer in 4") println(s"All data: ${c.exposed_storedData.peek().asString}") println(s"All lasts: ${printVecBinary(c.exposed_storedLasts.peek())}") }, { From e77a202ccd597bce62311c1453dd20b8722f5cd2 Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Wed, 8 May 2024 13:14:54 +0200 Subject: [PATCH 4/8] Remove compile warnings. Width type is now part of Chisel package. Source and sink clocks do not need to be initialized anymore. --- .../nl/tudelft/tydi_chisel/TydiLib.scala | 1 - .../examples/pipeline/PipelineExample.scala | 1 - .../tydi_chisel/examples/rgb/Rgb.scala | 1 - .../TimestampedMessage.scala | 1 - library/src/test/scala/gcd/GCDSpec.scala | 2 -- .../tydi_chisel/TydiStreamDriverTest.scala | 4 +-- .../tydi_chisel/chisel/ChiselQueueTest.scala | 30 +++++++++---------- .../pipeline/PipelineExamplePlusTest.scala | 16 +++++----- .../pipeline/PipelineExampleTest.scala | 16 +++++----- .../utils/ComplexityConverterTest.scala | 12 ++++---- 10 files changed, 38 insertions(+), 46 deletions(-) diff --git a/library/src/main/scala/nl/tudelft/tydi_chisel/TydiLib.scala b/library/src/main/scala/nl/tudelft/tydi_chisel/TydiLib.scala index 71f4385..d321c22 100644 --- a/library/src/main/scala/nl/tudelft/tydi_chisel/TydiLib.scala +++ b/library/src/main/scala/nl/tudelft/tydi_chisel/TydiLib.scala @@ -5,7 +5,6 @@ import scala.collection.mutable.ListBuffer import chisel3._ import chisel3.experimental.{BaseModule, ExtModule} -import chisel3.internal.firrtl.Width import chisel3.util.{log2Ceil, Cat} import nl.tudelft.tydi_chisel.ReverseTranspiler._ import nl.tudelft.tydi_chisel.utils.ComplexityConverter diff --git a/library/src/main/scala/nl/tudelft/tydi_chisel/examples/pipeline/PipelineExample.scala b/library/src/main/scala/nl/tudelft/tydi_chisel/examples/pipeline/PipelineExample.scala index 70a442c..cf96bf5 100644 --- a/library/src/main/scala/nl/tudelft/tydi_chisel/examples/pipeline/PipelineExample.scala +++ b/library/src/main/scala/nl/tudelft/tydi_chisel/examples/pipeline/PipelineExample.scala @@ -1,7 +1,6 @@ package nl.tudelft.tydi_chisel.examples.pipeline import chisel3._ -import chisel3.internal.firrtl.Width import chisel3.util.Counter import circt.stage.ChiselStage.{emitCHIRRTL, emitSystemVerilog} import nl.tudelft.tydi_chisel._ diff --git a/library/src/main/scala/nl/tudelft/tydi_chisel/examples/rgb/Rgb.scala b/library/src/main/scala/nl/tudelft/tydi_chisel/examples/rgb/Rgb.scala index be47ecf..dd869d7 100644 --- a/library/src/main/scala/nl/tudelft/tydi_chisel/examples/rgb/Rgb.scala +++ b/library/src/main/scala/nl/tudelft/tydi_chisel/examples/rgb/Rgb.scala @@ -1,7 +1,6 @@ package nl.tudelft.tydi_chisel.examples.rgb import chisel3._ -import chisel3.internal.firrtl.Width import circt.stage.ChiselStage.{emitCHIRRTL, emitSystemVerilog} import nl.tudelft.tydi_chisel._ diff --git a/library/src/main/scala/nl/tudelft/tydi_chisel/examples/timestamped_message/TimestampedMessage.scala b/library/src/main/scala/nl/tudelft/tydi_chisel/examples/timestamped_message/TimestampedMessage.scala index 172fbd9..0812001 100644 --- a/library/src/main/scala/nl/tudelft/tydi_chisel/examples/timestamped_message/TimestampedMessage.scala +++ b/library/src/main/scala/nl/tudelft/tydi_chisel/examples/timestamped_message/TimestampedMessage.scala @@ -1,7 +1,6 @@ package nl.tudelft.tydi_chisel.examples.timestamped_message import chisel3._ -import chisel3.internal.firrtl.Width import circt.stage.ChiselStage.{emitCHIRRTL, emitSystemVerilog} import nl.tudelft.tydi_chisel._ diff --git a/library/src/test/scala/gcd/GCDSpec.scala b/library/src/test/scala/gcd/GCDSpec.scala index 5e44f9a..1d84ab6 100644 --- a/library/src/test/scala/gcd/GCDSpec.scala +++ b/library/src/test/scala/gcd/GCDSpec.scala @@ -23,9 +23,7 @@ class GCDSpec extends AnyFreeSpec with ChiselScalatestTester { "Gcd should calculate proper greatest common denominator" in { test(new DecoupledGcd(16)) { dut => dut.input.initSource() - dut.input.setSourceClock(dut.clock) dut.output.initSink() - dut.output.setSinkClock(dut.clock) val testValues = for { x <- 0 to 10; y <- 0 to 10 } yield (x, y) val inputSeq = testValues.map { case (x, y) => (new GcdInputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U) } diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala index f1d9a45..290cb86 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala @@ -31,8 +31,8 @@ class TydiStreamDriverTest extends AnyFlatSpec with ChiselScalatestTester { it should "pass through an aggregate" in { test(new TydiPassthroughModule(new MyBundle)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val whatever: Seq[MyBundle => (Data, Data)] = Seq(_.a -> 0.U, _.b -> false.B) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/chisel/ChiselQueueTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/chisel/ChiselQueueTest.scala index 3fba94b..8269f44 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/chisel/ChiselQueueTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/chisel/ChiselQueueTest.scala @@ -56,8 +56,8 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { val myVec = Vec(2, bundle) test(new QueueModule(myVec, 2)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val testVal = myVec.Lit(0 -> bundle.Lit(_.a -> 42.U, _.b -> true.B), 1 -> bundle.Lit(_.a -> 43.U, _.b -> false.B)) val testVal2 = @@ -74,8 +74,8 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { val myVec = Vec(2, UInt(8.W)) test(new QueueModule(myVec, 2)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val testVal = myVec.Lit(0 -> 42.U, 1 -> 43.U) val testVal2 = myVec.Lit(0 -> 44.U, 1 -> 45.U) @@ -89,8 +89,8 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { it should "pass through an aggregate, using enqueueNow" in { test(new QueueModule(new MyBundle, 2)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val bundle = new MyBundle val testVal = bundle.Lit(_.a -> 42.U, _.b -> true.B) @@ -105,8 +105,8 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { it should "pass through elements, using enqueueNow" in { test(new QueueModule(UInt(8.W), 2)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() c.out.expectInvalid() c.in.enqueueNow(42.U) @@ -117,8 +117,8 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { it should "pass through elements, using enqueueSeq" in { test(new QueueModule(UInt(8.W), 2)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() fork { c.in.enqueueSeq(Seq(42.U, 43.U, 44.U)) @@ -138,9 +138,7 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { it should "work with a combinational queue" in { test(new PassthroughQueue(UInt(8.W))) { c => c.in.initSource() - c.in.setSourceClock(c.clock) c.out.initSink() - c.out.setSinkClock(c.clock) fork { c.in.enqueueSeq(Seq(42.U, 43.U, 44.U)) @@ -158,16 +156,16 @@ class ChiselQueueTest extends AnyFlatSpec with ChiselScalatestTester { }) io.out <> Queue(io.in) }) { c => - c.io.in.initSource().setSourceClock(c.clock) - c.io.out.initSink().setSinkClock(c.clock) + c.io.in.initSource() + c.io.out.initSink() parallel(c.io.in.enqueueSeq(Seq(5.U, 2.U)), c.io.out.expectDequeueSeq(Seq(5.U, 2.U))) } } it should "enqueue/dequeue zero-width data" in { test(new QueueModule(UInt(0.W), 2)) { c => - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() fork { c.in.enqueueSeq(Seq(0.U, 0.U, 0.U)) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala index 5eed5c7..8bb46c6 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala @@ -36,8 +36,8 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { it should "reduce" in { test(new ReducerWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val t1 = vecLitFromSeq(Seq(3, 6, 9, 28)) val t1Last = Vec.Lit(0.U, 0.U, 0.U, 1.U) @@ -71,8 +71,8 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { it should "process a sequence in the first half" in { test(new PipelineStartWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val t1 = vecLitFromSeq(Seq(-3, 6, 9, 28)) val t1Last = Vec.Lit(0.U, 0.U, 0.U, 1.U) @@ -96,8 +96,8 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { it should "process a sequence" in { test(new PipelineWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() val t1 = vecLitFromSeq(Seq(-3, 6, 9, 28)) val t1Last = Vec.Lit(0.U, 0.U, 0.U, 1.U) @@ -139,8 +139,8 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { it should "process a sequence in parallel" in { test(new PipelineWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() // define min and max values numbers are allowed to have val rangeMin = BigInt(Long.MinValue) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala index bc6d84c..6f1ccdb 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala @@ -16,8 +16,8 @@ class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester { it should "filter negative values" in { test(new NonNegativeFilterWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() parallel( c.in.enqueueElNow(_.time -> 123976.U, _.value -> 6.S), @@ -46,8 +46,8 @@ class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester { it should "reduce" in { test(new ReducerWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() c.in.enqueueElNow(_.time -> 123976.U, _.value -> 6.S) println(c.out.printState()) @@ -66,8 +66,8 @@ class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester { it should "process a sequence" in { test(new PipelineWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() // Enqueue first value c.in.enqueueElNow(_.time -> 123976.U, _.value -> 6.S) @@ -99,8 +99,8 @@ class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester { it should "process a sequence in parallel" in { test(new PipelineWrap) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() // define min and max values numbers are allowed to have val rangeMin = BigInt(Long.MinValue) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala index 2c2e025..56c3fe1 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala @@ -205,8 +205,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { // test case body here test(new ManualComplexityConverterFancyWrapper(new MyEl, stream, 10)) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() println("N=1 test with fancy wrapper") println("Initializing signals") // c.in.last.poke(c.in.last.Lit(0 -> 0.U)) @@ -306,8 +306,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { // test case body here test(new ManualComplexityConverterFancyWrapper(char, stream, 20)) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() c.in.endi.poke(stream.n - 1) c.in.strb.poke(0.U) println("She is a dolphin test") @@ -457,8 +457,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { // test case body here test(new ManualComplexityConverterFancyWrapper(char, stream, 20)) { c => // Initialize signals - c.in.initSource().setSourceClock(c.clock) - c.out.initSink().setSinkClock(c.clock) + c.in.initSource() + c.out.initSink() c.in.endi.poke(stream.n - 1) c.in.strb.poke(0.U) println("Hello World test") From fd91d493ebf49458ffdb154f92129dbef0c1364a Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Wed, 8 May 2024 14:13:37 +0200 Subject: [PATCH 5/8] Change consecutive parallel calls to parallel consecutive calls. With the V6 update the previous results in a poke after poke error. --- .../tydi_chisel/TydiStreamDriverTest.scala | 14 +++++----- .../pipeline/PipelineExampleTest.scala | 27 +++++++------------ 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala index 290cb86..31c7f50 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala @@ -42,13 +42,13 @@ class TydiStreamDriverTest extends AnyFlatSpec with ChiselScalatestTester { c.out.expectInvalid() c.clock.step() - parallel(c.in.enqueueElNow(testVal), c.out.expectDequeueNow(_.a -> 42.U, _.b -> true.B)) - // Clock step is required because else we are still in the same moment as the parallel functions from before. - // Because they are timescoped, the printState does not give very interesting results. -// c.clock.step() -// state = c.out.printState() -// print(state) - parallel(c.in.enqueueElNow(_.a -> 43.U, _.b -> false.B), c.out.expectDequeueNow(testVal2)) + parallel({ + c.in.enqueueElNow(testVal) + c.in.enqueueElNow(_.a -> 43.U, _.b -> false.B) + }, { + c.out.expectDequeueNow(_.a -> 42.U, _.b -> true.B) + c.out.expectDequeueNow(testVal2) + }) } } } diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala index 6f1ccdb..25380f5 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala @@ -20,24 +20,15 @@ class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester { c.out.initSink() parallel( - c.in.enqueueElNow(_.time -> 123976.U, _.value -> 6.S), - c.out.expectDequeueNow(_.time -> 123976.U, _.value -> 6.S) - ) - - parallel( - c.in.enqueueElNow(_.time -> 123976.U, _.value -> 0.S), - c.out.expectDequeueNow(_.time -> 123976.U, _.value -> 0.S) - ) - - parallel( - c.in.enqueueElNow(_.time -> 123976.U, _.value -> -7.S), - timescope { - c.out.ready.poke(true.B) - fork - .withRegion(Monitor) { - c.out.strb.expect(0.U) - } - .joinAndStep(c.clock) + { + c.in.enqueueElNow(_.time -> 123976.U, _.value -> 6.S) + c.in.enqueueElNow(_.time -> 123976.U, _.value -> 0.S) + c.in.enqueueElNow(_.time -> 123976.U, _.value -> -7.S) + }, + { + c.out.expectDequeueNow(c.out.elLit(_.time -> 123976.U, _.value -> 6.S)) + c.out.expectDequeueNow(c.out.elLit(_.time -> 123976.U, _.value -> 0.S)) + c.out.expectDequeueEmptyNow(strb = Some(0.U)) } ) } From 81511f03c95b9d91d902e2218fc5ea6a11a143d3 Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Wed, 8 May 2024 15:08:29 +0200 Subject: [PATCH 6/8] Add reset option to enqueue functions. This replaces the `timescope` functionality. --- .../tydi_chisel_test/TydiTesting.scala | 21 ++++++++++++------- .../pipeline/PipelineExamplePlusTest.scala | 6 +++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala index c248561..4c6079c 100644 --- a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala +++ b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala @@ -1,10 +1,9 @@ package nl.tudelft.tydi_chisel_test import scala.language.implicitConversions - import chisel3._ import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor -import chisel3.experimental.VecLiterals.AddVecLiteralConstructor +import chisel3.experimental.VecLiterals.{AddObjectLiteralConstructor, AddVecLiteralConstructor} import chisel3.util._ import chiseltest._ import nl.tudelft.tydi_chisel.{PhysicalStreamDetailed, TydiEl} @@ -24,8 +23,10 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.stai.poke(0.U) x.endi.poke((x.n - 1).U) x.strb.poke(((1 << x.n) - 1).U(x.n.W)) // Set strobe to all 1's -// val lasts = (0 until x.n).map(index => (index, 0.U)) -// x.last.poke(x.last.Lit(lasts: _*)) + if (x.d > 0) { + val lasts: Seq[UInt] = Seq.fill(x.n)(0.U(x.d.W)) + x.last.poke(Vec.Lit(lasts: _*)) + } this } @@ -49,7 +50,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None, - run: => Unit = {} + run: => Unit = {}, + reset: Boolean = false ): Unit = { x.el.poke(data) if (last.isDefined) { @@ -73,6 +75,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } .joinAndStep() x.valid.poke(false) + if (reset) { initSource() } } def enqueueNow( @@ -81,7 +84,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None, - run: => Unit = {} + run: => Unit = {}, + reset: Boolean = false ): Unit = { x.data.pokePartial(data) if (last.isDefined) { @@ -104,6 +108,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } .joinAndStep() x.valid.poke(false) + if (reset) { initSource() } } /** Send an empty transfer (no valid data lanes). Unless overridden, a strobe of 0's is sent. */ @@ -112,7 +117,8 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel strb: Option[UInt] = None, stai: Option[UInt] = None, endi: Option[UInt] = None, - run: => Unit = {} + run: => Unit = {}, + reset: Boolean = false ): Unit = { if (last.isDefined) { x.last.pokePartial(last.get) @@ -140,6 +146,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } .joinAndStep() x.valid.poke(true) + if (reset) { initSource() } } def enqueueElNow(elems: (Tel => (Data, Data))*): Unit = { diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala index 8bb46c6..7320ea9 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala @@ -42,7 +42,7 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { val t1 = vecLitFromSeq(Seq(3, 6, 9, 28)) val t1Last = Vec.Lit(0.U, 0.U, 0.U, 1.U) - c.in.enqueueNow(t1, endi = Some(2.U), last = Some(t1Last)) + c.in.enqueueNow(t1, endi = Some(2.U), last = Some(t1Last), reset=true) println(c.out.printState(statsRenderer)) c.clock.step() println(c.out.printState(statsRenderer)) @@ -57,10 +57,10 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { c.clock.step() println(c.out.printState(statsRenderer)) - c.in.enqueueNow(t2, endi = Some(3.U), last = Some(t2Last)) + c.in.enqueueNow(t2, endi = Some(3.U), last = Some(t2Last), reset=true) println(c.out.printState(statsRenderer)) c.out.expectInvalid() - c.in.enqueueNow(t3, endi = Some(3.U), last = Some(t3Last)) + c.in.enqueueNow(t3, endi = Some(3.U), last = Some(t3Last), reset=true) println(c.out.printState(statsRenderer)) c.clock.step() println(c.out.printState(statsRenderer)) From 96e2166f66fb007f467a79899e535610bb27160c Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Wed, 8 May 2024 15:32:32 +0200 Subject: [PATCH 7/8] Generalize and abstract enqueue/dequeue methods. Extract the common code. --- .../tydi_chisel_test/TydiTesting.scala | 153 ++++++++---------- 1 file changed, 63 insertions(+), 90 deletions(-) diff --git a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala index 4c6079c..bb58623 100644 --- a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala +++ b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala @@ -44,19 +44,20 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel Vec(x.n, UInt(x.d.W)).Lit(elems: _*) } - def enqueueElNow( - data: Tel, - last: Option[UInt] = None, - strb: Option[UInt] = None, - stai: Option[UInt] = None, - endi: Option[UInt] = None, - run: => Unit = {}, - reset: Boolean = false - ): Unit = { - x.el.poke(data) + private def _enqueueNow( + data: Option[Vec[Tel]], + last: Option[Vec[UInt]] = None, + strb: Option[UInt] = None, + stai: Option[UInt] = None, + endi: Option[UInt] = None, + run: => Unit = {}, + reset: Boolean = false + ): Unit = { + if (data.isDefined) { + x.data.pokePartial(data.get) + } if (last.isDefined) { - val lastLit = Vec(x.n, UInt(x.d.W)).Lit(0 -> last.get) - x.last.pokePartial(lastLit) + x.last.pokePartial(last.get) } if (strb.isDefined) { x.strb.poke(strb.get) @@ -78,6 +79,23 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel if (reset) { initSource() } } + def enqueueElNow( + data: Tel, + last: Option[UInt] = None, + strb: Option[UInt] = None, + stai: Option[UInt] = None, + endi: Option[UInt] = None, + run: => Unit = {}, + reset: Boolean = false + ): Unit = { + val lastLit = if (last.isDefined) { + Option(Vec(x.n, UInt(x.d.W)).Lit(0 -> last.get)) + } else { + None + } + _enqueueNow(Option(dataLit(0 -> data)), lastLit, strb, stai, endi, run, reset) + } + def enqueueNow( data: Vec[Tel], last: Option[Vec[UInt]] = None, @@ -87,28 +105,7 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel run: => Unit = {}, reset: Boolean = false ): Unit = { - x.data.pokePartial(data) - if (last.isDefined) { - x.last.pokePartial(last.get) - } - if (strb.isDefined) { - x.strb.poke(strb.get) - } - if (stai.isDefined) { - x.stai.poke(stai.get) - } - if (endi.isDefined) { - x.endi.poke(endi.get) - } - x.valid.poke(true) - run - fork - .withRegion(Monitor) { - x.ready.expect(true) - } - .joinAndStep() - x.valid.poke(false) - if (reset) { initSource() } + _enqueueNow(Option(data), last, strb, stai, endi, run, reset) } /** Send an empty transfer (no valid data lanes). Unless overridden, a strobe of 0's is sent. */ @@ -120,33 +117,12 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel run: => Unit = {}, reset: Boolean = false ): Unit = { - if (last.isDefined) { - x.last.pokePartial(last.get) - } /* else { - val litVals = Seq.tabulate(x.n)(i => (i -> 0.U)) - val lastLit = Vec(x.n, UInt(x.d.W)).Lit(litVals: _*) - x.last.poke(lastLit) - }*/ - if (strb.isDefined) { - x.strb.poke(strb.get) + val _strb = if (strb.isDefined) { + strb } else { - x.strb.poke(0.U) - } - if (stai.isDefined) { - x.stai.poke(stai.get) + Option(0.U) } - if (endi.isDefined) { - x.endi.poke(endi.get) - } - x.valid.poke(true) - run - fork - .withRegion(Monitor) { - x.ready.expect(true) - } - .joinAndStep() - x.valid.poke(true) - if (reset) { initSource() } + _enqueueNow(None, last, _strb, stai, endi, run, reset) } def enqueueElNow(elems: (Tel => (Data, Data))*): Unit = { @@ -216,20 +192,22 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel expectDequeue(litValue) } - def expectDequeueNow( - data: Tel, - last: Option[Vec[UInt]] = None, - strb: Option[UInt] = None, - stai: Option[UInt] = None, - endi: Option[UInt] = None, - run: => Unit = {} - ): Unit = { + private def _expectDequeueNow( + data: Option[Tel], + last: Option[Vec[UInt]] = None, + strb: Option[UInt] = None, + stai: Option[UInt] = None, + endi: Option[UInt] = None, + run: => Unit = {} + ): Unit = { x.ready.poke(true) fork .withRegion(Monitor) { x.valid.expect(true) run - x.el.expect(data) + if (data.isDefined) { + x.el.expect(data.get) + } if (last.isDefined) { x.last.expect(last.get) } @@ -247,6 +225,17 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel x.ready.poke(false) } + def expectDequeueNow( + data: Tel, + last: Option[Vec[UInt]] = None, + strb: Option[UInt] = None, + stai: Option[UInt] = None, + endi: Option[UInt] = None, + run: => Unit = {} + ): Unit = { + _expectDequeueNow(Option(data), last, strb, stai, endi, run) + } + /** Expect an empty transfer (no valid data lanes). Unless overridden, a strobe of 0's is expected. */ def expectDequeueEmptyNow( last: Option[Vec[UInt]] = None, @@ -255,28 +244,12 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel endi: Option[UInt] = None, run: => Unit = {} ): Unit = { - x.ready.poke(true) - fork - .withRegion(Monitor) { - x.valid.expect(true) - run - if (strb.isDefined) { - x.strb.expect(strb.get) - } else { - x.strb.expect(0.U) - } - if (last.isDefined) { - x.last.expect(last.get) - } - if (stai.isDefined) { - x.stai.expect(stai.get) - } - if (endi.isDefined) { - x.endi.expect(endi.get) - } - } - .joinAndStep() - x.ready.poke(false) + val _strb = if (strb.isDefined) { + strb + } else { + Option(0.U) + } + _expectDequeueNow(None, last, _strb, stai, endi, run) } def expectDequeueNow(elems: (Tel => (Data, Data))*): Unit = { From 85d69b36320c1d4eaf3f5b96d587121f74a375a4 Mon Sep 17 00:00:00 2001 From: Casper Cromjongh Date: Wed, 8 May 2024 15:34:28 +0200 Subject: [PATCH 8/8] PreCI. --- .../tydi_chisel_test/TydiTesting.scala | 39 ++++++++++--------- .../tydi_chisel/TydiStreamDriverTest.scala | 16 ++++---- .../pipeline/PipelineExamplePlusTest.scala | 6 +-- .../pipeline/PipelineExampleTest.scala | 3 +- .../utils/ComplexityConverterTest.scala | 21 ++++++---- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala index bb58623..cba6831 100644 --- a/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala +++ b/testing/src/main/scala/nl/tudelft/tydi_chisel_test/TydiTesting.scala @@ -1,6 +1,7 @@ package nl.tudelft.tydi_chisel_test import scala.language.implicitConversions + import chisel3._ import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor import chisel3.experimental.VecLiterals.{AddObjectLiteralConstructor, AddVecLiteralConstructor} @@ -45,14 +46,14 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } private def _enqueueNow( - data: Option[Vec[Tel]], - last: Option[Vec[UInt]] = None, - strb: Option[UInt] = None, - stai: Option[UInt] = None, - endi: Option[UInt] = None, - run: => Unit = {}, - reset: Boolean = false - ): Unit = { + data: Option[Vec[Tel]], + last: Option[Vec[UInt]] = None, + strb: Option[UInt] = None, + stai: Option[UInt] = None, + endi: Option[UInt] = None, + run: => Unit = {}, + reset: Boolean = false + ): Unit = { if (data.isDefined) { x.data.pokePartial(data.get) } @@ -162,9 +163,9 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } @deprecated("You no longer need to set the clock explicitly.", since = "6.0.x") - protected val decoupledSourceKey = new Object() + protected val decoupledSourceKey = new Object() def setSourceClock(clock: Clock): this.type = this - protected val decoupledSinkKey = new Object() + protected val decoupledSinkKey = new Object() @deprecated("You no longer need to set the clock explicitly.", since = "6.0.x") def setSinkClock(clock: Clock): this.type = this @@ -193,13 +194,13 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel } private def _expectDequeueNow( - data: Option[Tel], - last: Option[Vec[UInt]] = None, - strb: Option[UInt] = None, - stai: Option[UInt] = None, - endi: Option[UInt] = None, - run: => Unit = {} - ): Unit = { + data: Option[Tel], + last: Option[Vec[UInt]] = None, + strb: Option[UInt] = None, + stai: Option[UInt] = None, + endi: Option[UInt] = None, + run: => Unit = {} + ): Unit = { x.ready.poke(true) fork .withRegion(Monitor) { @@ -287,7 +288,9 @@ class TydiStreamDriver[Tel <: TydiEl, Tus <: Data](x: PhysicalStreamDetailed[Tel val streamAntiDir = if (x.r) out else in try - stringBuilder.append(s"State of \"${x.instanceName}\" $streamDir @ clk-step ${x.getSourceClock().getStepCount}:\n") + stringBuilder.append( + s"State of \"${x.instanceName}\" $streamDir @ clk-step ${x.getSourceClock().getStepCount}:\n" + ) catch { case e: ClockResolutionException => stringBuilder.append(s"State of \"${x.instanceName}\" $streamDir (unable to get clock):\n") diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala index 31c7f50..66b8318 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/TydiStreamDriverTest.scala @@ -42,13 +42,15 @@ class TydiStreamDriverTest extends AnyFlatSpec with ChiselScalatestTester { c.out.expectInvalid() c.clock.step() - parallel({ - c.in.enqueueElNow(testVal) - c.in.enqueueElNow(_.a -> 43.U, _.b -> false.B) - }, { - c.out.expectDequeueNow(_.a -> 42.U, _.b -> true.B) - c.out.expectDequeueNow(testVal2) - }) + parallel( + { + c.in.enqueueElNow(testVal) + c.in.enqueueElNow(_.a -> 43.U, _.b -> false.B) + }, { + c.out.expectDequeueNow(_.a -> 42.U, _.b -> true.B) + c.out.expectDequeueNow(testVal2) + } + ) } } } diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala index 7320ea9..3606f49 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExamplePlusTest.scala @@ -42,7 +42,7 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { val t1 = vecLitFromSeq(Seq(3, 6, 9, 28)) val t1Last = Vec.Lit(0.U, 0.U, 0.U, 1.U) - c.in.enqueueNow(t1, endi = Some(2.U), last = Some(t1Last), reset=true) + c.in.enqueueNow(t1, endi = Some(2.U), last = Some(t1Last), reset = true) println(c.out.printState(statsRenderer)) c.clock.step() println(c.out.printState(statsRenderer)) @@ -57,10 +57,10 @@ class PipelineExamplePlusTest extends AnyFlatSpec with ChiselScalatestTester { c.clock.step() println(c.out.printState(statsRenderer)) - c.in.enqueueNow(t2, endi = Some(3.U), last = Some(t2Last), reset=true) + c.in.enqueueNow(t2, endi = Some(3.U), last = Some(t2Last), reset = true) println(c.out.printState(statsRenderer)) c.out.expectInvalid() - c.in.enqueueNow(t3, endi = Some(3.U), last = Some(t3Last), reset=true) + c.in.enqueueNow(t3, endi = Some(3.U), last = Some(t3Last), reset = true) println(c.out.printState(statsRenderer)) c.clock.step() println(c.out.printState(statsRenderer)) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala index 25380f5..a735713 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/pipeline/PipelineExampleTest.scala @@ -24,8 +24,7 @@ class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester { c.in.enqueueElNow(_.time -> 123976.U, _.value -> 6.S) c.in.enqueueElNow(_.time -> 123976.U, _.value -> 0.S) c.in.enqueueElNow(_.time -> 123976.U, _.value -> -7.S) - }, - { + }, { c.out.expectDequeueNow(c.out.elLit(_.time -> 123976.U, _.value -> 6.S)) c.out.expectDequeueNow(c.out.elLit(_.time -> 123976.U, _.value -> 0.S)) c.out.expectDequeueEmptyNow(strb = Some(0.U)) diff --git a/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala b/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala index 56c3fe1..ff6ca09 100644 --- a/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala +++ b/testing/src/test/scala/nl/tudelft/tydi_chisel/utils/ComplexityConverterTest.scala @@ -327,7 +327,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { { // Send some data in // shei - c.in.enqueueNow(t1, + c.in.enqueueNow( + t1, Option(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b00".U)), Option(bRev("1111")), run = { @@ -340,7 +341,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { c.clock.step(1) // s_a_ - c.in.enqueueNow(t3, + c.in.enqueueNow( + t3, Option(Vec.Lit("b01".U(2.W), "b00".U, "b01".U, "b00".U)), Option(bRev("1010")), run = { @@ -351,7 +353,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { println(s"All data: ${c.exposed_storedData.peek().asString}") // d_ol - c.in.enqueueNow(t4, + c.in.enqueueNow( + t4, Option(Vec.Lit("b00".U(2.W), "b00".U, "b00".U, "b00".U)), Option(bRev("1011")), run = { @@ -362,7 +365,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { println(s"All data: ${c.exposed_storedData.peek().asString}") // ph__ - c.in.enqueueNow(t5, + c.in.enqueueNow( + t5, Option(Vec.Lit("b00".U(2.W), "b00".U, "b00".U, "b00".U)), Option(bRev("1100")), run = { @@ -373,7 +377,8 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { println(s"All data: ${c.exposed_storedData.peek().asString}") // __in - c.in.enqueueNow(t6, + c.in.enqueueNow( + t6, None, Option(bRev("0011")), run = { @@ -505,9 +510,11 @@ class ComplexityConverterTest extends AnyFlatSpec with ChiselScalatestTester { println(s"All data: ${c.exposed_storedData.peek().asString}") // ce____ - c.in.enqueueNow(t4, + c.in.enqueueNow( + t4, last = Some(Vec.Lit("b00".U(2.W), "b00".U, "b01".U, "b10".U, "b11".U, "b10".U)), - strb = Some(bRev("110000"))) + strb = Some(bRev("110000")) + ) print(c.in.printState(charRenderer)) println("\n-- Transfer in 4")