summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/AnalogIntegrationSpec.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/scala/chiselTests/AnalogIntegrationSpec.scala')
-rw-r--r--src/test/scala/chiselTests/AnalogIntegrationSpec.scala128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala
new file mode 100644
index 00000000..92f89e06
--- /dev/null
+++ b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala
@@ -0,0 +1,128 @@
+// See LICENSE for license details.
+
+package chiselTests
+
+import chisel3._
+import chisel3.util._
+import chisel3.testers.BasicTester
+import chisel3.experimental._
+
+/* This test is different from AnalogSpec in that it uses more complicated black boxes that can each
+ * drive the bidirectional bus. It was created to evaluate Analog with synthesis tools since the
+ * simple tests in AnalogSpec don't anything interesting in them to synthesize.
+ */
+
+class AnalogBlackBoxPort extends Bundle {
+ val in = Input(Valid(UInt(32.W)))
+ val out = Output(UInt(32.W))
+}
+
+// This IO can be used for a single BlackBox or to group multiple
+// Has multiple ports for driving and checking but only one shared bus
+class AnalogBlackBoxIO(n: Int) extends Bundle {
+ require(n > 0)
+ val bus = Analog(32.W)
+ val port = Vec(n, new AnalogBlackBoxPort)
+}
+
+// Assigns bus to out
+// Assigns in.bits + index to bus when in.valid
+class AnalogBlackBox(index: Int) extends BlackBox(Map("index" -> index)) {
+ val io = IO(new AnalogBlackBoxIO(1))
+}
+
+// Wraps up n blackboxes, connecing their buses and simply forwarding their ports up
+class AnalogBlackBoxWrapper(n: Int, idxs: Seq[Int]) extends Module {
+ require(n > 0)
+ val io = IO(new AnalogBlackBoxIO(n))
+ val bbs = idxs.map(i => Module(new AnalogBlackBox(i)))
+ io.bus <> bbs.head.io.bus // Always bulk connect io.bus to first bus
+ io.port <> bbs.flatMap(_.io.port) // Connect ports
+ attach(bbs.map(_.io.bus):_*) // Attach all the buses
+}
+
+// Common superclass for AnalogDUT and AnalogSmallDUT
+abstract class AnalogDUTModule(numBlackBoxes: Int) extends Module {
+ require(numBlackBoxes > 0)
+ val io = IO(new Bundle {
+ val ports = Vec(numBlackBoxes, new AnalogBlackBoxPort)
+ })
+}
+
+/** Single test case for lots of things
+ *
+ * $ - Wire at top connecting child inouts (Done in AnalogDUT)
+ * $ - Port inout connected to 1 or more children inouts (AnalogBackBoxWrapper)
+ * $ - Multiple port inouts connected (AnalogConnector)
+ */
+class AnalogDUT extends AnalogDUTModule(5) { // 5 BlackBoxes
+ val mods = Seq(
+ Module(new AnalogBlackBoxWrapper(1, Seq(0))),
+ Module(new AnalogBlackBox(1)),
+ Module(new AnalogBlackBoxWrapper(2, Seq(2, 3))), // 2 blackboxes
+ Module(new AnalogBlackBox(4))
+ )
+ // Connect all ports to top
+ io.ports <> mods.flatMap(_.io.port)
+ // Attach first 3 Modules
+ attach(mods.take(3).map(_.io.bus):_*)
+ // Attach last module to 1st through AnalogConnector
+ val con = Module(new AnalogConnector)
+ attach(con.io.bus1, mods.head.io.bus)
+ attach(con.io.bus2, mods.last.io.bus)
+}
+
+/** Same as [[AnalogDUT]] except it omits [[AnalogConnector]] because that is currently not
+ * supported by Verilator
+ * @todo Delete once Verilator can handle [[AnalogDUT]]
+ */
+class AnalogSmallDUT extends AnalogDUTModule(4) { // 4 BlackBoxes
+ val mods = Seq(
+ Module(new AnalogBlackBoxWrapper(1, Seq(0))),
+ Module(new AnalogBlackBox(1)),
+ Module(new AnalogBlackBoxWrapper(2, Seq(2, 3))) // 2 BlackBoxes
+ )
+ // Connect all ports to top
+ io.ports <> mods.flatMap(_.io.port)
+ // Attach first 3 Modules
+ attach(mods.take(3).map(_.io.bus):_*)
+}
+
+
+// This tester is primarily intended to be able to pass the dut to synthesis
+class AnalogIntegrationTester(mod: => AnalogDUTModule) extends BasicTester {
+ val BusValue = 2.U(32.W) // arbitrary
+
+ val dut = Module(mod)
+
+ val expectedValue = Wire(UInt(32.W))
+ expectedValue := BusValue // Overridden each cycle
+
+ val (cycle, done) = Counter(true.B, dut.io.ports.size)
+ for ((dut, idx) <- dut.io.ports.zipWithIndex) {
+ printf(p"@$cycle: BlackBox #$idx: $dut\n")
+ // Defaults
+ dut.in.valid := false.B
+ dut.in.bits := BusValue
+ // Error checking
+ assert(dut.out === expectedValue)
+
+ when (cycle === idx.U) {
+ expectedValue := BusValue + idx.U
+ dut.in.valid := true.B
+
+ }
+ }
+ when (done) { stop() }
+}
+
+class AnalogIntegrationSpec extends ChiselFlatSpec {
+ behavior of "Verilator"
+ it should "support simple bidirectional wires" in {
+ assertTesterPasses(new AnalogIntegrationTester(new AnalogSmallDUT), Seq("/AnalogBlackBox.v"))
+ }
+ // Use this test once Verilator supports alias
+ ignore should "support arbitrary bidirectional wires" in {
+ assertTesterPasses(new AnalogIntegrationTester(new AnalogDUT), Seq("/AnalogBlackBox.v"))
+ }
+}