summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/experimental
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/experimental
parent8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff)
cleanup
Diffstat (limited to 'src/test/scala/chiselTests/experimental')
-rw-r--r--src/test/scala/chiselTests/experimental/DataMirrorSpec.scala91
-rw-r--r--src/test/scala/chiselTests/experimental/DataView.scala557
-rw-r--r--src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala57
-rw-r--r--src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala176
-rw-r--r--src/test/scala/chiselTests/experimental/FlatIOSpec.scala68
-rw-r--r--src/test/scala/chiselTests/experimental/ForceNames.scala128
-rw-r--r--src/test/scala/chiselTests/experimental/GroupSpec.scala115
-rw-r--r--src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala91
-rw-r--r--src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala73
-rw-r--r--src/test/scala/chiselTests/experimental/TraceSpec.scala328
-rw-r--r--src/test/scala/chiselTests/experimental/Tuple.scala163
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala32
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala599
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Examples.scala340
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala1146
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala495
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Utils.scala21
17 files changed, 0 insertions, 4480 deletions
diff --git a/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala b/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala
deleted file mode 100644
index 09fdf3c4..00000000
--- a/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.util.Valid
-import chisel3.stage.ChiselStage
-import chisel3.experimental.DataMirror
-import chiselTests.ChiselFlatSpec
-
-object DataMirrorSpec {
- import org.scalatest.matchers.should.Matchers._
- class GrandChild(parent: RawModule) extends Module {
- DataMirror.getParent(this) should be(Some(parent))
- }
- class Child(parent: RawModule) extends Module {
- val inst = Module(new GrandChild(this))
- DataMirror.getParent(inst) should be(Some(this))
- DataMirror.getParent(this) should be(Some(parent))
- }
- class Parent extends Module {
- val inst = Module(new Child(this))
- DataMirror.getParent(inst) should be(Some(this))
- DataMirror.getParent(this) should be(None)
- }
-}
-
-class DataMirrorSpec extends ChiselFlatSpec {
- import DataMirrorSpec._
-
- behavior.of("DataMirror")
-
- def assertBinding(x: Data, io: Boolean, wire: Boolean, reg: Boolean) = {
- DataMirror.isIO(x) should be(io)
- DataMirror.isWire(x) should be(wire)
- DataMirror.isReg(x) should be(reg)
- }
-
- def assertIO(x: Data) = assertBinding(x, true, false, false)
-
- def assertWire(x: Data) = assertBinding(x, false, true, false)
-
- def assertReg(x: Data) = assertBinding(x, false, false, true)
-
- def assertNone(x: Data) = assertBinding(x, false, false, false)
-
- it should "validate bindings" in {
- class MyModule extends Module {
- val typ = UInt(4.W)
- val vectyp = Vec(8, UInt(4.W))
- val io = IO(new Bundle {
- val in = Input(UInt(4.W))
- val vec = Input(vectyp)
- val out = Output(UInt(4.W))
- })
- val vec = Wire(vectyp)
- val regvec = Reg(vectyp)
- val wire = Wire(UInt(4.W))
- val reg = RegNext(wire)
-
- assertIO(io)
- assertIO(io.in)
- assertIO(io.out)
- assertIO(io.vec(1))
- assertIO(io.vec)
- assertWire(vec)
- assertWire(vec(0))
- assertWire(wire)
- assertReg(reg)
- assertReg(regvec)
- assertReg(regvec(2))
- assertNone(typ)
- assertNone(vectyp)
- }
- ChiselStage.elaborate(new MyModule)
- }
-
- it should "support getParent for normal modules" in {
- ChiselStage.elaborate(new Parent)
- }
-
- it should "support getParent for normal modules even when used in a D/I context" in {
- import chisel3.experimental.hierarchy._
- class Top extends Module {
- val defn = Definition(new Parent)
- val inst = Instance(defn)
- DataMirror.getParent(this) should be(None)
- }
- ChiselStage.elaborate(new Top)
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/DataView.scala b/src/test/scala/chiselTests/experimental/DataView.scala
deleted file mode 100644
index cefc893c..00000000
--- a/src/test/scala/chiselTests/experimental/DataView.scala
+++ /dev/null
@@ -1,557 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.experimental.dataview._
-import chisel3.experimental.conversions._
-import chisel3.experimental.DataMirror.internal.chiselTypeClone
-import chisel3.experimental.{Analog, HWTuple2}
-import chisel3.stage.ChiselStage
-import chisel3.util.{Decoupled, DecoupledIO}
-
-object SimpleBundleDataView {
- class BundleA(val w: Int) extends Bundle {
- val foo = UInt(w.W)
- }
- class BundleB(val w: Int) extends Bundle {
- val bar = UInt(w.W)
- }
- implicit val v1 = DataView[BundleA, BundleB](a => new BundleB(a.w), _.foo -> _.bar)
- implicit val v2 = v1.invert(b => new BundleA(b.w))
-}
-
-object VecBundleDataView {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
- implicit val v1: DataView[MyBundle, Vec[UInt]] = DataView(_ => Vec(2, UInt(8.W)), _.foo -> _(1), _.bar -> _(0))
- implicit val v2 = v1.invert(_ => new MyBundle)
-}
-
-object FlatDecoupledDataView {
- class FizzBuzz extends Bundle {
- val fizz = UInt(8.W)
- val buzz = UInt(8.W)
- }
- class FlatDecoupled extends Bundle {
- val valid = Output(Bool())
- val ready = Input(Bool())
- val fizz = Output(UInt(8.W))
- val buzz = Output(UInt(8.W))
- }
- implicit val view = DataView[FlatDecoupled, DecoupledIO[FizzBuzz]](
- _ => Decoupled(new FizzBuzz),
- _.valid -> _.valid,
- _.ready -> _.ready,
- _.fizz -> _.bits.fizz,
- _.buzz -> _.bits.buzz
- )
- implicit val view2 = view.invert(_ => new FlatDecoupled)
-}
-
-class DataViewSpec extends ChiselFlatSpec {
-
- behavior.of("DataView")
-
- it should "support simple Bundle viewing" in {
- import SimpleBundleDataView._
- class MyModule extends Module {
- val in = IO(Input(new BundleA(8)))
- val out = IO(Output(new BundleB(8)))
- out := in.viewAs[BundleB]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("out.bar <= in.foo")
- }
-
- it should "be a bidirectional mapping" in {
- import SimpleBundleDataView._
- class MyModule extends Module {
- val in = IO(Input(new BundleA(8)))
- val out = IO(Output(new BundleB(8)))
- out.viewAs[BundleA] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("out.bar <= in.foo")
- }
-
- it should "handle viewing UInts as UInts" in {
- class MyModule extends Module {
- val in = IO(Input(UInt(8.W)))
- val foo = IO(Output(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- foo := in.viewAs[UInt]
- bar.viewAs[UInt] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("foo <= in")
- chirrtl should include("bar <= in")
- }
-
- it should "handle viewing Analogs as Analogs" in {
- class MyModule extends Module {
- val foo = IO(Analog(8.W))
- val bar = IO(Analog(8.W))
- foo <> bar.viewAs[Analog]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("attach (foo, bar)")
- }
-
- it should "handle viewing Bundles as their same concrete type" in {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- }
- class MyModule extends Module {
- val in = IO(Input(new MyBundle))
- val fizz = IO(Output(new MyBundle))
- val buzz = IO(Output(new MyBundle))
- fizz := in.viewAs[MyBundle]
- buzz.viewAs[MyBundle] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("fizz <= in")
- chirrtl should include("buzz <= in")
- }
-
- it should "handle viewing Vecs as their same concrete type" in {
- class MyModule extends Module {
- val in = IO(Input(Vec(1, UInt(8.W))))
- val fizz = IO(Output(Vec(1, UInt(8.W))))
- val buzz = IO(Output(Vec(1, UInt(8.W))))
- fizz := in.viewAs[Vec[UInt]]
- buzz.viewAs[Vec[UInt]] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("fizz <= in")
- chirrtl should include("buzz <= in")
- }
-
- it should "handle viewing Vecs as Bundles and vice versa" in {
- import VecBundleDataView._
- class MyModule extends Module {
- val in = IO(Input(new MyBundle))
- val out = IO(Output(Vec(2, UInt(8.W))))
- val out2 = IO(Output(Vec(2, UInt(8.W))))
- out := in.viewAs[Vec[UInt]]
- out2.viewAs[MyBundle] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("out[0] <= in.bar")
- chirrtl should include("out[1] <= in.foo")
- chirrtl should include("out2[0] <= in.bar")
- chirrtl should include("out2[1] <= in.foo")
- }
-
- it should "work with bidirectional connections for nested types" in {
- import FlatDecoupledDataView._
- class MyModule extends Module {
- val enq = IO(Flipped(Decoupled(new FizzBuzz)))
- val deq = IO(new FlatDecoupled)
- val deq2 = IO(new FlatDecoupled)
- deq <> enq.viewAs[FlatDecoupled]
- deq2.viewAs[DecoupledIO[FizzBuzz]] <> enq
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("deq.valid <= enq.valid")
- chirrtl should include("enq.ready <= deq.ready")
- chirrtl should include("deq.fizz <= enq.bits.fizz")
- chirrtl should include("deq.buzz <= enq.bits.buzz")
- chirrtl should include("deq2.valid <= enq.valid")
- chirrtl should include("enq.ready <= deq2.ready")
- chirrtl should include("deq2.fizz <= enq.bits.fizz")
- chirrtl should include("deq2.buzz <= enq.bits.buzz")
- }
-
- it should "support viewing a Bundle as a Parent Bundle type" in {
- class Foo extends Bundle {
- val foo = UInt(8.W)
- }
- class Bar extends Foo {
- val bar = UInt(8.W)
- }
- class MyModule extends Module {
- val fooIn = IO(Input(new Foo))
- val barOut = IO(Output(new Bar))
- barOut.viewAsSupertype(new Foo) := fooIn
-
- val barIn = IO(Input(new Bar))
- val fooOut = IO(Output(new Foo))
- fooOut := barIn.viewAsSupertype(new Foo)
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("barOut.foo <= fooIn.foo")
- chirrtl should include("fooOut.foo <= barIn.foo")
- }
-
- it should "be easy to make a PartialDataView viewing a Bundle as a Parent Bundle type" in {
- class Foo(x: Int) extends Bundle {
- val foo = UInt(x.W)
- }
- class Bar(val x: Int) extends Foo(x) {
- val bar = UInt(x.W)
- }
- implicit val view = PartialDataView.supertype[Bar, Foo](b => new Foo(b.x))
- class MyModule extends Module {
- val fooIn = IO(Input(new Foo(8)))
- val barOut = IO(Output(new Bar(8)))
- barOut.viewAs[Foo] := fooIn
-
- val barIn = IO(Input(new Bar(8)))
- val fooOut = IO(Output(new Foo(8)))
- fooOut := barIn.viewAs[Foo]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("barOut.foo <= fooIn.foo")
- chirrtl should include("fooOut.foo <= barIn.foo")
- }
-
- it should "error if viewing a parent Bundle as a child Bundle type" in {
- assertTypeError("""
- class Foo extends Bundle {
- val foo = UInt(8.W)
- }
- class Bar extends Foo {
- val bar = UInt(8.W)
- }
- class MyModule extends Module {
- val barIn = IO(Input(new Bar))
- val fooOut = IO(Output(new Foo))
- fooOut.viewAs(new Bar) := barIn
- }
- """)
- }
-
- it should "work in UInt operations" in {
- class MyBundle extends Bundle {
- val value = UInt(8.W)
- }
- class MyModule extends Module {
- val a = IO(Input(UInt(8.W)))
- val b = IO(Input(new MyBundle))
- val cond = IO(Input(Bool()))
- val and, mux, bitsCat = IO(Output(UInt(8.W)))
- // Chisel unconditionally emits a node, so name it at least
- val x = a.viewAs[UInt] & b.viewAs[MyBundle].value
- and.viewAs[UInt] := x
-
- val y = Mux(cond.viewAs[Bool], a.viewAs[UInt], b.value.viewAs[UInt])
- mux.viewAs[UInt] := y
-
- // TODO should we have a macro so that we don't need .apply?
- val aBits = a.viewAs[UInt].apply(3, 0)
- val bBits = b.viewAs[MyBundle].value(3, 0)
- val abCat = aBits.viewAs[UInt] ## bBits.viewAs[UInt]
- bitsCat := abCat
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- val expected = List(
- "node x = and(a, b.value)",
- "and <= x",
- "node y = mux(cond, a, b.value)",
- "mux <= y",
- "node aBits = bits(a, 3, 0)",
- "node bBits = bits(b.value, 3, 0)",
- "node abCat = cat(aBits, bBits)",
- "bitsCat <= abCat"
- )
- for (line <- expected) {
- chirrtl should include(line)
- }
- }
-
- it should "support .asUInt of Views" in {
- import VecBundleDataView._
- class MyModule extends Module {
- val barIn = IO(Input(new MyBundle))
- val fooOut = IO(Output(UInt()))
- val cat = barIn.viewAs[Vec[UInt]].asUInt
- fooOut := cat
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("node cat = cat(barIn.foo, barIn.bar)")
- chirrtl should include("fooOut <= cat")
- }
-
- it should "be composable" in {
- // Given DataView[A, B] and DataView[B, C], derive DataView[A, C]
- class Foo(val foo: UInt) extends Bundle
- class Bar(val bar: UInt) extends Bundle
- class Fizz(val fizz: UInt) extends Bundle
-
- implicit val foo2bar = DataView[Foo, Bar](f => new Bar(chiselTypeClone(f.foo)), _.foo -> _.bar)
- implicit val bar2fizz = DataView[Bar, Fizz](b => new Fizz(chiselTypeClone(b.bar)), _.bar -> _.fizz)
-
- implicit val foo2fizz: DataView[Foo, Fizz] = foo2bar.andThen(bar2fizz)
-
- class MyModule extends Module {
- val a, b = IO(Input(new Foo(UInt(8.W))))
- val y, z = IO(Output(new Fizz(UInt(8.W))))
- y := a.viewAs[Fizz]
- z := b.viewAs[Bar].viewAs[Fizz]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("y.fizz <= a.foo")
- chirrtl should include("z.fizz <= b.foo")
- }
-
- it should "enable using Seq like Data" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val y, z = IO(Output(UInt(8.W)))
- // Unclear why the implicit conversion does not work in this case for Seq
- // That being said, it's easy enough to cast via `.viewAs` with or without
- Seq(y, z) := Mux(sel, Seq(a, b).viewAs, Seq(c, d).viewAs[Vec[UInt]])
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign y = sel ? a : c;")
- verilog should include("assign z = sel ? b : d;")
- }
-
- // This example should be turned into a built-in feature
- it should "enable viewing Seqs as Vecs" in {
-
- class MyModule extends Module {
- val a, b, c = IO(Input(UInt(8.W)))
- val x, y, z = IO(Output(UInt(8.W)))
- Seq(x, y, z) := VecInit(a, b, c)
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign x = a;")
- verilog should include("assign y = b;")
- verilog should include("assign z = c;")
- }
-
- it should "support recursive composition of views" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val w, x, y, z = IO(Output(UInt(8.W)))
-
- // A little annoying that we need the type annotation on VecInit to get the implicit conversion to work
- // Note that one can just use the Seq on the RHS so there is an alternative (may lack discoverability)
- // We could also overload `VecInit` instead of relying on the implicit conversion
- Seq((w, x), (y, z)) := VecInit[HWTuple2[UInt, UInt]]((a, b), (c, d))
- }
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign w = a;")
- verilog should include("assign x = b;")
- verilog should include("assign y = c;")
- verilog should include("assign z = d;")
- }
-
- it should "support dynamic indexing for Vec identity views" in {
- class MyModule extends Module {
- val dataIn = IO(Input(UInt(8.W)))
- val addr = IO(Input(UInt(2.W)))
- val dataOut = IO(Output(UInt(8.W)))
-
- val vec = RegInit(0.U.asTypeOf(Vec(4, UInt(8.W))))
- val view = vec.viewAs[Vec[UInt]]
- // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
- // This style is not recommended, this is just testing the behavior
- val selected = view(addr)
- selected := dataIn
- dataOut := selected
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("vec[addr] <= dataIn")
- chirrtl should include("dataOut <= vec[addr]")
- }
-
- it should "support dynamic indexing for Vecs that correspond 1:1 in a view" in {
- class MyBundle extends Bundle {
- val foo = Vec(4, UInt(8.W))
- val bar = UInt(2.W)
- }
- implicit val myView = DataView[(Vec[UInt], UInt), MyBundle](
- _ => new MyBundle,
- _._1 -> _.foo,
- _._2 -> _.bar
- )
- class MyModule extends Module {
- val dataIn = IO(Input(UInt(8.W)))
- val addr = IO(Input(UInt(2.W)))
- val dataOut = IO(Output(UInt(8.W)))
-
- val vec = RegInit(0.U.asTypeOf(Vec(4, UInt(8.W))))
- val addrReg = Reg(UInt(2.W))
- val view = (vec, addrReg).viewAs[MyBundle]
- // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
- // This style is not recommended, this is just testing the behavior
- val selected = view.foo(view.bar)
- view.bar := addr
- selected := dataIn
- dataOut := selected
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("vec[addrReg] <= dataIn")
- chirrtl should include("dataOut <= vec[addrReg]")
- }
-
- it should "error if you try to dynamically index a Vec view that does not correspond to a Vec target" in {
- class MyModule extends Module {
- val inA, inB = IO(Input(UInt(8.W)))
- val outA, outB = IO(Output(UInt(8.W)))
- val idx = IO(Input(UInt(1.W)))
-
- val a, b, c, d = RegInit(0.U)
-
- // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
- // This style is not recommended, this is just testing the behavior
- val selected = Seq((a, b), (c, d)).apply(idx)
- selected := (inA, inB)
- (outA, outB) := selected
- }
- (the[InvalidViewException] thrownBy {
- ChiselStage.emitChirrtl(new MyModule)
- }).getMessage should include("Dynamic indexing of Views is not yet supported")
- }
-
- it should "error if the mapping is non-total in the view" in {
- class MyBundle(val foo: UInt, val bar: UInt) extends Bundle
- implicit val dv = DataView[UInt, MyBundle](_ => new MyBundle(UInt(), UInt()), _ -> _.bar)
- class MyModule extends Module {
- val tpe = new MyBundle(UInt(8.W), UInt(8.W))
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(tpe))
- out := in.viewAs[MyBundle]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View field '_.foo' is missing")
- }
-
- it should "error if the mapping is non-total in the target" in {
- implicit val dv = DataView[(UInt, UInt), UInt](_ => UInt(), _._1 -> _)
- class MyModule extends Module {
- val a, b = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := (a, b).viewAs[UInt]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("Target field '_._2' is missing")
- }
-
- it should "error if the mapping contains Data that are not part of the Target" in {
- class BundleA extends Bundle {
- val foo = UInt(8.W)
- }
- class BundleB extends Bundle {
- val fizz = UInt(8.W)
- val buzz = UInt(8.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.fizz, (_, b) => (3.U, b.buzz))
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out := in.viewAs[BundleB]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View mapping must only contain Elements within the Target")
- }
-
- it should "error if the mapping contains Data that are not part of the View" in {
- class BundleA extends Bundle {
- val foo = UInt(8.W)
- }
- class BundleB extends Bundle {
- val fizz = UInt(8.W)
- val buzz = UInt(8.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.fizz, (_, b) => (3.U, b.buzz))
- implicit val dv2 = dv.invert(_ => new BundleA)
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out.viewAs[BundleA] := in
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View mapping must only contain Elements within the View")
- }
-
- it should "error if a view has a width that does not match the target" in {
- class BundleA extends Bundle {
- val foo = UInt(8.W)
- }
- class BundleB extends Bundle {
- val bar = UInt(4.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.bar)
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out := in.viewAs[BundleB]
- }
- val err = the[InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule)
- val expected = """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <8>""".r
- (err.getMessage should fullyMatch).regex(expected)
- }
-
- it should "error if a view has a known width when the target width is unknown" in {
- class BundleA extends Bundle {
- val foo = UInt()
- }
- class BundleB extends Bundle {
- val bar = UInt(4.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.bar)
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out := in.viewAs[BundleB]
- }
- val err = the[InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule)
- val expected =
- """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <unknown>""".r
- (err.getMessage should fullyMatch).regex(expected)
- }
-
- it should "support invalidation" in {
- class MyModule extends Module {
- val a, b, c, d, e, f = IO(Output(UInt(8.W)))
- val foo = (a, b).viewAs
- val bar = (c, d).viewAs
- val fizz = (e, f).viewAs
- foo := DontCare
- bar <> DontCare
- fizz._1 := DontCare
- fizz._2 <> DontCare
- }
-
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- val expected = ('a' to 'f').map(c => s"$c is invalid")
- for (line <- expected) {
- chirrtl should include(line)
- }
- }
-
- behavior.of("PartialDataView")
-
- it should "still error if the mapping is non-total in the view" in {
- class MyBundle(val foo: UInt, val bar: UInt) extends Bundle
- implicit val dv = PartialDataView[UInt, MyBundle](_ => new MyBundle(UInt(), UInt()), _ -> _.bar)
- class MyModule extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(new MyBundle(UInt(8.W), UInt(8.W))))
- out := in.viewAs[MyBundle]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View field '_.foo' is missing")
- }
-
- it should "NOT error if the mapping is non-total in the target" in {
- implicit val dv = PartialDataView[(UInt, UInt), UInt](_ => UInt(), _._2 -> _)
- class MyModule extends Module {
- val a, b = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := (a, b).viewAs[UInt]
- }
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign out = b;")
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala b/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala
deleted file mode 100644
index 4704a942..00000000
--- a/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.experimental.{BaseModule, ExtModule}
-import chisel3.experimental.dataview._
-import chisel3.util.{log2Ceil, Decoupled, DecoupledIO, Queue, QueueIO}
-import chiselTests.ChiselFlatSpec
-import firrtl.transforms.DontTouchAnnotation
-
-// Let's put it all together!
-object DataViewIntegrationSpec {
-
- class QueueIntf[T <: Data](gen: T, entries: Int) extends Bundle {
- val ports = new QueueIO(gen, entries)
- // Let's grab a reference to something internal too
- // Output because can't have directioned and undirectioned stuff
- val enq_ptr = Output(UInt(log2Ceil(entries).W))
- }
-
- // It's not clear if a view of a Module ever _can_ be total since internal nodes are part of the Module
- implicit def queueView[T <: Data] = PartialDataView[Queue[T], QueueIntf[T]](
- q => new QueueIntf(q.gen, q.entries),
- _.io -> _.ports,
- // Some token internal signal
- _.enq_ptr.value -> _.enq_ptr
- )
-
- object MyQueue {
- def apply[T <: Data](enq: DecoupledIO[T], n: Int): QueueIntf[T] = {
- val queue = Module(new Queue[T](enq.bits.cloneType, n))
- val view = queue.viewAs[QueueIntf[T]]
- view.ports.enq <> enq
- view
- }
- }
-
- class MyModule extends Module {
- val enq = IO(Flipped(Decoupled(UInt(8.W))))
- val deq = IO(Decoupled(UInt(8.W)))
-
- val queue = MyQueue(enq, 4)
- deq <> queue.ports.deq
- dontTouch(queue.enq_ptr)
- }
-}
-
-class DataViewIntegrationSpec extends ChiselFlatSpec {
- import DataViewIntegrationSpec.MyModule
-
- "Users" should "be able to view and annotate Modules" in {
- val (_, annos) = getFirrtlAndAnnos(new MyModule)
- val ts = annos.collect { case DontTouchAnnotation(t) => t.serialize }
- ts should equal(Seq("~MyModule|Queue>enq_ptr_value"))
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala b/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
deleted file mode 100644
index ddeeab6e..00000000
--- a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
+++ /dev/null
@@ -1,176 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.experimental.dataview._
-import chisel3.experimental.conversions._
-import chisel3.experimental.{annotate, ChiselAnnotation}
-import chiselTests.ChiselFlatSpec
-
-object DataViewTargetSpec {
- import firrtl.annotations._
- private case class DummyAnno(target: ReferenceTarget, id: Int) extends SingleTargetAnnotation[ReferenceTarget] {
- override def duplicate(n: ReferenceTarget) = this.copy(target = n)
- }
- private def mark(d: Data, id: Int) = annotate(new ChiselAnnotation {
- override def toFirrtl: Annotation = DummyAnno(d.toTarget, id)
- })
- private def markAbs(d: Data, id: Int) = annotate(new ChiselAnnotation {
- override def toFirrtl: Annotation = DummyAnno(d.toAbsoluteTarget, id)
- })
-}
-
-class DataViewTargetSpec extends ChiselFlatSpec {
- import DataViewTargetSpec._
- private val checks: Seq[Data => String] = Seq(
- _.toTarget.toString,
- _.toAbsoluteTarget.toString,
- _.instanceName,
- _.pathName,
- _.parentPathName,
- _.parentModName
- )
-
- // Check helpers
- private def checkAll(impl: Data, refs: String*): Unit = {
- refs.size should be(checks.size)
- for ((check, value) <- checks.zip(refs)) {
- check(impl) should be(value)
- }
- }
- private def checkSameAs(impl: Data, refs: Data*): Unit =
- for (ref <- refs) {
- checkAll(impl, checks.map(_(ref)): _*)
- }
-
- behavior.of("DataView Naming")
-
- it should "support views of Elements" in {
- class MyChild extends Module {
- val out = IO(Output(UInt(8.W)))
- val insideView = out.viewAs[UInt]
- out := 0.U
- }
- class MyParent extends Module {
- val out = IO(Output(UInt(8.W)))
- val inst = Module(new MyChild)
- out := inst.out
- }
- val m = elaborateAndGetModule(new MyParent)
- val outsideView = m.inst.out.viewAs[UInt]
- checkSameAs(m.inst.out, m.inst.insideView, outsideView)
- }
-
- it should "support 1:1 mappings of Aggregates and their children" in {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- val bars = Vec(2, UInt(8.W))
- }
- implicit val dv =
- DataView[MyBundle, Vec[UInt]](_ => Vec(3, UInt(8.W)), _.foo -> _(0), _.bars(0) -> _(1), _.bars(1) -> _(2))
- class MyChild extends Module {
- val out = IO(Output(new MyBundle))
- val outView = out.viewAs[Vec[UInt]] // Note different type
- val outFooView = out.foo.viewAs[UInt]
- val outBarsView = out.bars.viewAs[Vec[UInt]]
- val outBars0View = out.bars(0).viewAs[UInt]
- out := 0.U.asTypeOf(new MyBundle)
- }
- class MyParent extends Module {
- val out = IO(Output(new MyBundle))
- val inst = Module(new MyChild)
- out := inst.out
- }
- val m = elaborateAndGetModule(new MyParent)
- val outView = m.inst.out.viewAs[Vec[UInt]] // Note different type
- val outFooView = m.inst.out.foo.viewAs[UInt]
- val outBarsView = m.inst.out.bars.viewAs[Vec[UInt]]
- val outBars0View = m.inst.out.bars(0).viewAs[UInt]
-
- checkSameAs(m.inst.out, m.inst.outView, outView)
- checkSameAs(m.inst.out.foo, m.inst.outFooView, m.inst.outView(0), outFooView, outView(0))
- checkSameAs(m.inst.out.bars, m.inst.outBarsView, outBarsView)
- checkSameAs(
- m.inst.out.bars(0),
- m.inst.outBars0View,
- outBars0View,
- m.inst.outView(1),
- outView(1),
- m.inst.outBarsView(0),
- outBarsView(0)
- )
- }
-
- // Ideally this would work 1:1 but that requires changing the binding
- it should "support annotation renaming of Aggregate children of Aggregate views" in {
- class MyBundle extends Bundle {
- val foo = Vec(2, UInt(8.W))
- }
- class MyChild extends Module {
- val out = IO(Output(new MyBundle))
- val outView = out.viewAs[MyBundle]
- mark(out.foo, 0)
- mark(outView.foo, 1)
- markAbs(out.foo, 2)
- markAbs(outView, 3)
- out := 0.U.asTypeOf(new MyBundle)
- }
- class MyParent extends Module {
- val out = IO(Output(new MyBundle))
- val inst = Module(new MyChild)
- out := inst.out
- }
- val (_, annos) = getFirrtlAndAnnos(new MyParent)
- val pairs = annos.collect { case DummyAnno(t, idx) => (idx, t.toString) }.sortBy(_._1)
- val expected = Seq(
- 0 -> "~MyParent|MyChild>out.foo",
- 1 -> "~MyParent|MyChild>out.foo",
- 2 -> "~MyParent|MyParent/inst:MyChild>out.foo",
- 3 -> "~MyParent|MyParent/inst:MyChild>out"
- )
- pairs should equal(expected)
- }
-
- it should "support annotating views that cannot be mapped to a single ReferenceTarget" in {
- class MyBundle extends Bundle {
- val a, b = Input(UInt(8.W))
- val c, d = Output(UInt(8.W))
- }
- // Note that each use of a Tuple as Data causes an implicit conversion creating a View
- class MyChild extends Module {
- val io = IO(new MyBundle)
- (io.c, io.d) := (io.a, io.b)
- // The type annotations create the views via the implicit conversion
- val view1: Data = (io.a, io.b)
- val view2: Data = (io.c, io.d)
- mark(view1, 0)
- mark(view2, 1)
- markAbs(view1, 2)
- markAbs(view2, 3)
- mark((io.b, io.d), 4) // Mix it up for fun
- }
- class MyParent extends Module {
- val io = IO(new MyBundle)
- val inst = Module(new MyChild)
- io <> inst.io
- }
- val (_, annos) = getFirrtlAndAnnos(new MyParent)
- val pairs = annos.collect { case DummyAnno(t, idx) => (idx, t.toString) }.sorted
- val expected = Seq(
- 0 -> "~MyParent|MyChild>io.a",
- 0 -> "~MyParent|MyChild>io.b",
- 1 -> "~MyParent|MyChild>io.c",
- 1 -> "~MyParent|MyChild>io.d",
- 2 -> "~MyParent|MyParent/inst:MyChild>io.a",
- 2 -> "~MyParent|MyParent/inst:MyChild>io.b",
- 3 -> "~MyParent|MyParent/inst:MyChild>io.c",
- 3 -> "~MyParent|MyParent/inst:MyChild>io.d",
- 4 -> "~MyParent|MyChild>io.b",
- 4 -> "~MyParent|MyChild>io.d"
- )
- pairs should equal(expected)
- }
-
- // TODO check these properties when using @instance API (especially preservation of totality)
-}
diff --git a/src/test/scala/chiselTests/experimental/FlatIOSpec.scala b/src/test/scala/chiselTests/experimental/FlatIOSpec.scala
deleted file mode 100644
index fb3f64c7..00000000
--- a/src/test/scala/chiselTests/experimental/FlatIOSpec.scala
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.util.Valid
-import chisel3.stage.ChiselStage.emitChirrtl
-import chisel3.experimental.{Analog, FlatIO}
-import chiselTests.ChiselFlatSpec
-
-class FlatIOSpec extends ChiselFlatSpec {
- behavior.of("FlatIO")
-
- it should "create ports without a prefix" in {
- class MyModule extends RawModule {
- val io = FlatIO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- io.out := io.in
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("input in : UInt<8>")
- chirrtl should include("output out : UInt<8>")
- chirrtl should include("out <= in")
- }
-
- it should "support bulk connections between FlatIOs and regular IOs" in {
- class MyModule extends RawModule {
- val in = FlatIO(Input(Valid(UInt(8.W))))
- val out = IO(Output(Valid(UInt(8.W))))
- out := in
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("out.bits <= bits")
- chirrtl should include("out.valid <= valid")
- }
-
- it should "dynamically indexing Vecs inside of FlatIOs" in {
- class MyModule extends RawModule {
- val io = FlatIO(new Bundle {
- val addr = Input(UInt(2.W))
- val in = Input(Vec(4, UInt(8.W)))
- val out = Output(Vec(4, UInt(8.W)))
- })
- io.out(io.addr) := io.in(io.addr)
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("out[addr] <= in[addr]")
- }
-
- it should "support Analog members" in {
- class MyBundle extends Bundle {
- val foo = Output(UInt(8.W))
- val bar = Analog(8.W)
- }
- class MyModule extends RawModule {
- val io = FlatIO(new Bundle {
- val in = Flipped(new MyBundle)
- val out = new MyBundle
- })
- io.out <> io.in
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("out.foo <= in.foo")
- chirrtl should include("attach (out.bar, in.bar)")
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/ForceNames.scala b/src/test/scala/chiselTests/experimental/ForceNames.scala
deleted file mode 100644
index 9ba825c4..00000000
--- a/src/test/scala/chiselTests/experimental/ForceNames.scala
+++ /dev/null
@@ -1,128 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests
-
-import firrtl._
-import chisel3._
-import chisel3.experimental.annotate
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.experimental.{forceName, ForceNameAnnotation, ForceNamesTransform, InlineInstance}
-import firrtl.annotations.{Annotation, ReferenceTarget}
-import firrtl.options.{Dependency, TargetDirAnnotation}
-import firrtl.stage.RunFirrtlTransformAnnotation
-import logger.{LogLevel, LogLevelAnnotation}
-
-/** Object containing Modules used for testing */
-object ForceNamesHierarchy {
- class WrapperExample extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- val inst = Module(new Wrapper)
- inst.in := in
- out := inst.out
- forceName(out, "outt")
- }
- class Wrapper extends Module with InlineInstance {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- val inst = Module(new MyLeaf)
- forceName(inst, "inst")
- inst.in := in
- out := inst.out
- }
- class MyLeaf extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- out := in
- }
- class RenamePortsExample extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- val inst = Module(new MyLeaf)
- inst.in := in
- out := inst.out
- forceName(inst.in, "inn")
- }
- class ConflictingName extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- out := in
- forceName(out, "in")
- }
- class BundleName extends Module {
- val in = IO(new Bundle {
- val a = Input(UInt(3.W))
- val b = Input(UInt(3.W))
- })
- val out = IO(Output(UInt(3.W)))
- out := in.a + in.b
- }
-}
-
-class ForceNamesSpec extends ChiselFlatSpec with Utils {
-
- def run[T <: RawModule](
- dut: => T,
- testName: String,
- inputAnnos: Seq[Annotation] = Nil,
- info: LogLevel.Value = LogLevel.None
- ): Iterable[String] = {
- def stage = new ChiselStage {
- override val targets = Seq(
- Dependency[chisel3.stage.phases.Elaborate],
- Dependency[chisel3.stage.phases.Convert],
- Dependency[firrtl.stage.phases.Compiler]
- )
- }
-
- val annos = List(
- TargetDirAnnotation("test_run_dir/ForceNames"),
- LogLevelAnnotation(info),
- ChiselGeneratorAnnotation(() => dut)
- ) ++ inputAnnos
-
- val ret = stage.execute(Array(), annos)
- val verilog = ret.collectFirst {
- case e: EmittedVerilogCircuitAnnotation => e.value.value
- }.get
-
- verilog.split("\\\n")
- }
- "Force Names on a wrapping instance" should "work" in {
- val verilog = run(new ForceNamesHierarchy.WrapperExample, "wrapper")
- exactly(1, verilog) should include("MyLeaf inst")
- }
- "Force Names on an instance port" should "work" in {
- val verilog = run(new ForceNamesHierarchy.RenamePortsExample, "instports")
- atLeast(1, verilog) should include("input [2:0] inn")
- }
- "Force Names with a conflicting name" should "error" in {
- intercept[CustomTransformException] {
- run(new ForceNamesHierarchy.ConflictingName, "conflicts")
- }
- }
- "Force Names of an intermediate bundle" should "error" in {
- intercept[CustomTransformException] {
- run(
- new ForceNamesHierarchy.BundleName,
- "bundlename",
- Seq(ForceNameAnnotation(ReferenceTarget("BundleName", "BundleName", Nil, "in", Nil), "inn"))
- )
- }
- }
-
- "Force Name of non-hardware value" should "warn" in {
- class Example extends Module {
- val tpe = UInt(8.W)
- forceName(tpe, "foobar")
-
- val in = IO(Input(tpe))
- val out = IO(Output(tpe))
- out := in
- }
-
- val (log, foo) = grabLog(chisel3.stage.ChiselStage.elaborate(new Example))
- log should include("deprecated")
- log should include("Using forceName 'foobar' on non-hardware value UInt<8>")
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/GroupSpec.scala b/src/test/scala/chiselTests/experimental/GroupSpec.scala
deleted file mode 100644
index 5e0c34bb..00000000
--- a/src/test/scala/chiselTests/experimental/GroupSpec.scala
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.RawModule
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.experimental.group
-import firrtl.analyses.InstanceGraph
-import firrtl.options.TargetDirAnnotation
-import firrtl.stage.CompilerAnnotation
-import firrtl.{LowFirrtlCompiler, ir => fir}
-
-import scala.collection.mutable
-
-class GroupSpec extends ChiselFlatSpec {
-
- def collectInstances(c: fir.Circuit, top: Option[String] = None): Seq[String] =
- new InstanceGraph(c).fullHierarchy.values.flatten.toSeq
- .map(v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString("."))
-
- def collectDeclarations(m: fir.DefModule): Set[String] = {
- val decs = mutable.HashSet[String]()
- def onStmt(s: fir.Statement): fir.Statement = s.mapStmt(onStmt) match {
- case d: fir.IsDeclaration => decs += d.name; d
- case other => other
- }
- m.mapStmt(onStmt)
- decs.toSet
- }
-
- def lower[T <: RawModule](gen: () => T): fir.Circuit = {
- (new ChiselStage)
- .execute(Array("--compiler", "low", "--target-dir", "test_run_dir"), Seq(ChiselGeneratorAnnotation(gen)))
- .collectFirst {
- case firrtl.stage.FirrtlCircuitAnnotation(circuit) => circuit
- }
- .get
- }
-
- "Module Grouping" should "compile to low FIRRTL" in {
- class MyModule extends Module {
- val io = IO(new Bundle {
- val a = Input(Bool())
- val b = Output(Bool())
- })
- val reg1 = RegInit(0.U)
- reg1 := io.a
- val reg2 = RegNext(reg1)
- io.b := reg2
- group(Seq(reg1, reg2), "DosRegisters", "doubleReg")
- }
-
- val firrtlCircuit = lower(() => new MyModule)
- firrtlCircuit.modules.collect {
- case m: fir.Module if m.name == "MyModule" =>
- Set("doubleReg") should be(collectDeclarations(m))
- case m: fir.Module if m.name == "DosRegisters" =>
- Set("reg1", "reg2") should be(collectDeclarations(m))
- }
- val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet
- Set("MyModule", "MyModule.doubleReg") should be(instances)
- }
-
- "Module Grouping" should "not include intermediate registers" in {
- class MyModule extends Module {
- val io = IO(new Bundle {
- val a = Input(Bool())
- val b = Output(Bool())
- })
- val reg1 = RegInit(0.U)
- reg1 := io.a
- val reg2 = RegNext(reg1)
- val reg3 = RegNext(reg2)
- io.b := reg3
- group(Seq(reg1, reg3), "DosRegisters", "doubleReg")
- }
-
- val firrtlCircuit = lower(() => new MyModule)
- firrtlCircuit.modules.collect {
- case m: fir.Module if m.name == "MyModule" =>
- Set("reg2", "doubleReg") should be(collectDeclarations(m))
- case m: fir.Module if m.name == "DosRegisters" =>
- Set("reg1", "reg3") should be(collectDeclarations(m))
- }
- val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet
- Set("MyModule", "MyModule.doubleReg") should be(instances)
- }
-
- "Module Grouping" should "include intermediate wires" in {
- class MyModule extends Module {
- val io = IO(new Bundle {
- val a = Input(Bool())
- val b = Output(Bool())
- })
- val reg1 = RegInit(0.U)
- reg1 := io.a
- val wire = WireInit(reg1)
- val reg3 = RegNext(wire)
- io.b := reg3
- group(Seq(reg1, reg3), "DosRegisters", "doubleReg")
- }
-
- val firrtlCircuit = lower(() => new MyModule)
- firrtlCircuit.modules.collect {
- case m: fir.Module if m.name == "MyModule" =>
- Set("doubleReg") should be(collectDeclarations(m))
- case m: fir.Module if m.name == "DosRegisters" =>
- Set("reg1", "reg3", "wire") should be(collectDeclarations(m))
- }
- val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet
- Set("MyModule", "MyModule.doubleReg") should be(instances)
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala b/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala
deleted file mode 100644
index 713f9d04..00000000
--- a/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.experimental.{BaseModule, ExtModule}
-import chisel3.experimental.dataview.DataProduct
-import chiselTests.ChiselFlatSpec
-
-object ModuleDataProductSpec {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
- trait MyIntf extends BaseModule {
- val in = IO(Input(new MyBundle))
- val out = IO(Output(new MyBundle))
- }
- class Passthrough extends RawModule {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := in
- }
- class MyUserModule extends Module with MyIntf {
- val inst = Module(new Passthrough)
- inst.in := in.foo
- val r = RegNext(in)
- out := r
- }
-
- class MyExtModule extends ExtModule with MyIntf
- class MyExtModuleWrapper extends RawModule with MyIntf {
- val inst = Module(new MyExtModule)
- inst.in := in
- out := inst.out
- }
-}
-
-class ModuleDataProductSpec extends ChiselFlatSpec {
- import ModuleDataProductSpec._
-
- behavior.of("DataProduct")
-
- it should "work for UserModules (recursively)" in {
- val m = elaborateAndGetModule(new MyUserModule)
- val expected = Seq(
- m.clock -> "m.clock",
- m.reset -> "m.reset",
- m.in -> "m.in",
- m.in.foo -> "m.in.foo",
- m.in.bar -> "m.in.bar",
- m.out -> "m.out",
- m.out.foo -> "m.out.foo",
- m.out.bar -> "m.out.bar",
- m.r -> "m.r",
- m.r.foo -> "m.r.foo",
- m.r.bar -> "m.r.bar",
- m.inst.in -> "m.inst.in",
- m.inst.out -> "m.inst.out"
- )
-
- val impl = implicitly[DataProduct[MyUserModule]]
- val set = impl.dataSet(m)
- for ((d, _) <- expected) {
- set(d) should be(true)
- }
- val it = impl.dataIterator(m, "m")
- it.toList should contain theSameElementsAs (expected)
- }
-
- it should "work for (wrapped) ExtModules" in {
- val m = elaborateAndGetModule(new MyExtModuleWrapper).inst
- val expected = Seq(
- m.in -> "m.in",
- m.in.foo -> "m.in.foo",
- m.in.bar -> "m.in.bar",
- m.out -> "m.out",
- m.out.foo -> "m.out.foo",
- m.out.bar -> "m.out.bar"
- )
-
- val impl = implicitly[DataProduct[MyExtModule]]
- val set = impl.dataSet(m)
- for ((d, _) <- expected) {
- set(d) should be(true)
- }
- val it = impl.dataIterator(m, "m")
- it.toList should contain theSameElementsAs (expected)
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala b/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala
deleted file mode 100644
index 64aabb4b..00000000
--- a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-package experimental
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-// NOTE This is currently an experimental API and subject to change
-// Example using a private port
-class PrivatePort extends NamedModuleTester {
- private val port = expectName(IO(Input(UInt(8.W))), "foo")
- port.suggestName("foo")
-}
-
-// Example of using composition to add ports to a Module
-class CompositionalPort(module: NamedModuleTester, name: String) {
- import chisel3.experimental.IO
- val foo = module.expectName(IO(Output(Bool())), name)
- foo.suggestName(name)
- foo := true.B
-}
-
-class CompositionalPortTester extends NamedModuleTester {
- val a = new CompositionalPort(this, "cheese")
- val b = new CompositionalPort(this, "tart")
-}
-
-class PortsWinTester extends NamedModuleTester {
- val wire = expectName(Wire(UInt()), "wire_1")
- val foo = expectName(Wire(UInt()).suggestName("wire"), "wire_2")
- val output = expectName(IO(Output(UInt())).suggestName("wire"), "wire")
-}
-
-class ProgrammaticPortsSpec extends ChiselFlatSpec with Utils {
-
- private def doTest(testMod: => NamedModuleTester): Unit = {
- var module: NamedModuleTester = null
- ChiselStage.elaborate { module = testMod; module }
- assert(module.getNameFailures() == Nil)
- }
-
- "Programmatic port creation" should "be supported" in {
- doTest(new PrivatePort)
- }
-
- "Calling IO outside of a Module definition" should "be supported" in {
- doTest(new CompositionalPortTester)
- }
-
- "Ports" should "always win over internal components in naming" in {
- doTest(new PortsWinTester)
- }
-
- "Module" should "ignore suggestName on clock and reset" in {
- doTest(new Module with NamedModuleTester {
- val io = IO(new Bundle {
- val foo = Output(UInt(8.W))
- })
- expectName(clock.suggestName("tart"), "clock")
- expectName(reset.suggestName("teser"), "reset")
- })
- }
-
- "SuggestName collisions on ports" should "be illegal" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new Module {
- val foo = IO(UInt(8.W)).suggestName("apple")
- val bar = IO(UInt(8.W)).suggestName("apple")
- })
- }
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/TraceSpec.scala b/src/test/scala/chiselTests/experimental/TraceSpec.scala
deleted file mode 100644
index 1d67ba0b..00000000
--- a/src/test/scala/chiselTests/experimental/TraceSpec.scala
+++ /dev/null
@@ -1,328 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.Trace._
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage, DesignAnnotation}
-import chisel3.util.experimental.InlineInstance
-import firrtl.AnnotationSeq
-import firrtl.annotations.TargetToken.{Instance, OfModule, Ref}
-import firrtl.annotations.{CompleteTarget, InstanceTarget, ReferenceTarget}
-import org.scalatest.matchers.should.Matchers
-
-class TraceSpec extends ChiselFlatSpec with Matchers {
-
- def refTarget(topName: String, ref: String, path: Seq[(Instance, OfModule)] = Seq()) =
- ReferenceTarget(topName, topName, path, ref, Seq())
-
- def instTarget(topName: String, instance: String, ofModule: String, path: Seq[(Instance, OfModule)] = Seq()) =
- InstanceTarget(topName, topName, path, instance, ofModule)
-
- def compile(testName: String, gen: () => Module): (os.Path, AnnotationSeq) = {
- val testDir = os.Path(createTestDirectory(testName).getAbsolutePath)
- val annos = (new ChiselStage).execute(
- Array("--target-dir", s"$testDir"),
- Seq(
- ChiselGeneratorAnnotation(gen)
- )
- )
- (testDir, annos)
- }
-
- "TraceFromAnnotations" should "be able to get nested name." in {
- class Bundle0 extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = Enum0.Type
- }
-
- class Bundle1 extends Bundle {
- val a = new Bundle0
- val b = Vec(4, Vec(4, Bool()))
- }
-
- class Module0 extends Module {
- val i = IO(Input(new Bundle1))
- val o = IO(Output(new Bundle1))
- val r = Reg(new Bundle1)
- o := r
- r := i
-
- traceName(r)
- traceName(i)
- traceName(o)
- }
-
- class Module1 extends Module {
- val i = IO(Input(new Bundle1))
- val m0 = Module(new Module0)
- m0.i := i
- m0.o := DontCare
- }
-
- object Enum0 extends ChiselEnum {
- val s0, s1, s2 = Value
- }
-
- val (testDir, annos) = compile("TraceFromAnnotaions", () => new Module1)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[Module1]
- // out of Builder.
-
- val oneTarget = finalTarget(annos)(dut.m0.r.a.a).head
- val ioTarget = finalTarget(annos)(dut.m0.i.b(1)(2)).head
-
- val topName = "Module1"
- oneTarget should be(refTarget(topName, "r_a_a", Seq(Instance("m0") -> OfModule("Module0"))))
-
- ioTarget should be(refTarget(topName, "i_b_1_2", Seq(Instance("m0") -> OfModule("Module0"))))
-
- // Below codes doesn't needs to be a FIRRTL Transform.
- def generateVerilatorConfigFile(data: Seq[Data], annos: AnnotationSeq): String =
- """`verilator_config
- |lint_off -rule unused
- |lint_off -rule declfilename
- |""".stripMargin +
- data
- .flatMap(finalTarget(annos))
- .toSet
- .map { target: CompleteTarget =>
- s"""public_flat_rd -module "${target.tokens.collectFirst {
- case OfModule(m) => m
- }.get}" -var "${target.tokens.collectFirst { case Ref(r) => r }.get}""""
- }
- .mkString("\n") + "\n"
-
- def verilatorTemplate(data: Seq[Data], annos: AnnotationSeq): String = {
- val vpiNames = data.flatMap(finalTarget(annos)).map { ct =>
- s"""TOP.${ct.circuit}.${ct.path.map { case (Instance(i), _) => i }.mkString(".")}.${ct.tokens.collectFirst {
- case Ref(r) => r
- }.get}"""
- }
- s"""
- |#include "V${topName}.h"
- |#include "verilated_vpi.h"
- |#include <memory>
- |#include <verilated.h>
- |
- |int vpiGetInt(const char name[]) {
- | vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8 *)name, NULL);
- | if (!vh1)
- | vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found");
- | s_vpi_value v;
- | v.format = vpiIntVal;
- | vpi_get_value(vh1, &v);
- | return v.value.integer;
- |}
- |
- |int main(int argc, char **argv) {
- | const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
- | contextp->commandArgs(argc, argv);
- | const std::unique_ptr<V$topName> top{new V$topName{contextp.get(), "TOP"}};
- | top->reset = 0;
- | top->clock = 0;
- | int a_b = 1;
- | top->i_a_b = a_b;
- | bool started = false;
- | int ticks = 20;
- | while (ticks--) {
- | contextp->timeInc(1);
- | top->clock = !top->clock;
- | if (!top->clock) {
- | if (contextp->time() > 1 && contextp->time() < 10) {
- | top->reset = 1;
- | } else {
- | top->reset = 0;
- | started = true;
- | }
- | a_b = a_b ? 0 : 1;
- | top->i_a_b = a_b;
- | }
- | top->eval();
- | VerilatedVpi::callValueCbs();
- | if (started && !top->clock) {
- | const int i = top->i_a_b;
- | const int o = vpiGetInt("${vpiNames.head}");
- | if (i == o)
- | vl_fatal(__FILE__, __LINE__, "sim_main", "${vpiNames.head} should be the old value of Module1.i_a_b");
- | printf("${vpiNames.head}=%d Module1.m0.o_a_b=%d\\n", i, o);
- | }
- | }
- | top->final();
- | return 0;
- |}
- |""".stripMargin
- }
-
- val config = os.temp(dir = testDir, contents = generateVerilatorConfigFile(Seq(dut.m0.o.a.b), annos))
- val verilog = testDir / s"$topName.v"
- val cpp = os.temp(dir = testDir, suffix = ".cpp", contents = verilatorTemplate(Seq(dut.m0.o.a.b), annos))
- val exe = testDir / "obj_dir" / s"V$topName"
- os.proc("verilator", "-Wall", "--cc", "--exe", "--build", "--vpi", s"$cpp", s"$verilog", s"$config")
- .call(stdout = os.Inherit, stderr = os.Inherit, cwd = testDir)
- assert(
- os.proc(s"$exe").call(stdout = os.Inherit, stderr = os.Inherit).exitCode == 0,
- "verilator should exit peacefully"
- )
- }
-
- "TraceFromCollideBundle" should "work" in {
- class CollideModule extends Module {
- val a = IO(
- Input(
- Vec(
- 2,
- new Bundle {
- val b = Flipped(Bool())
- val c = Vec(
- 2,
- new Bundle {
- val d = UInt(2.W)
- val e = Flipped(UInt(3.W))
- }
- )
- val c_1_e = UInt(4.W)
- }
- )
- )
- )
- val a_0_c = IO(Output(UInt(5.W)))
- val a__0 = IO(Output(UInt(5.W)))
- a_0_c := DontCare
- a__0 := DontCare
-
- traceName(a)
- traceName(a_0_c)
- traceName(a__0)
- }
-
- val (_, annos) = compile("TraceFromCollideBundle", () => new CollideModule)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[CollideModule]
-
- val topName = "CollideModule"
-
- val a0 = finalTarget(annos)(dut.a(0))
- val a__0 = finalTarget(annos)(dut.a__0).head
- val a__0_ref = refTarget(topName, "a__0")
- a0.foreach(_ shouldNot be(a__0_ref))
- a__0 should be(a__0_ref)
-
- val a0_c = finalTarget(annos)(dut.a(0).c)
- val a_0_c = finalTarget(annos)(dut.a_0_c).head
- val a_0_c_ref = refTarget(topName, "a_0_c")
- a0_c.foreach(_ shouldNot be(a_0_c_ref))
- a_0_c should be(a_0_c_ref)
-
- val a0_c1_e = finalTarget(annos)(dut.a(0).c(1).e).head
- val a0_c_1_e = finalTarget(annos)(dut.a(0).c_1_e).head
- a0_c1_e should be(refTarget(topName, "a_0_c__1_e"))
- a0_c_1_e should be(refTarget(topName, "a_0_c_1_e"))
- }
-
- "Inline should work" should "work" in {
- class Module0 extends Module {
- val i = IO(Input(Bool()))
- val o = IO(Output(Bool()))
- traceName(i)
- o := !i
- }
-
- class Module1 extends Module {
- val i = IO(Input(Bool()))
- val o = IO(Output(Bool()))
- val m0 = Module(new Module0 with InlineInstance)
- m0.i := i
- o := m0.o
- }
-
- val (_, annos) = compile("Inline", () => new Module1)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[Module1]
-
- val m0_i = finalTarget(annos)(dut.m0.i).head
- m0_i should be(refTarget("Module1", "m0_i"))
- }
-
- "Constant Propagation" should "be turned off by traceName" in {
- class Module0 extends Module {
- val i = WireDefault(1.U)
- val i0 = i + 1.U
- val o = IO(Output(UInt(2.W)))
- traceName(i0)
- o := i0
- }
-
- val (_, annos) = compile("ConstantProp", () => new Module0)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[Module0]
-
- val i0 = finalTarget(annos)(dut.i0).head
- i0 should be(refTarget("Module0", "i0"))
- }
-
- "Nested Module" should "work" in {
- class Io extends Bundle {
- val i = Input(Bool())
- val o = Output(Bool())
- }
-
- class Not extends Module {
- val io = IO(new Io)
- io.o := !io.i
- }
-
- class M1 extends Module {
- val io = IO(new Io)
- val not = Module(new Not)
- not.io <> io
- }
-
- class M2 extends Module {
- val io = IO(new Io)
- val m1 = Module(new M1 with InlineInstance)
- val not = Module(new Not)
-
- m1.io.i := io.i
- not.io.i := io.i
-
- io.o := m1.io.o && not.io.o
- }
-
- class M3 extends Module {
- val io = IO(new Io)
- val m2 = Module(new M2)
- io <> m2.io
- traceName(m2.not)
- traceName(m2.m1.not)
- }
-
- val (_, annos) = compile("NestedModule", () => new M3)
- val m3 = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[M3]
-
- val m2_m1_not = finalTarget(annos)(m3.m2.m1.not).head
- val m2_not = finalTarget(annos)(m3.m2.not).head
-
- m2_m1_not should be(instTarget("M3", "m1_not", "Not", Seq(Instance("m2") -> OfModule("M2"))))
- m2_not should be(instTarget("M3", "not", "Not", Seq(Instance("m2") -> OfModule("M2"))))
- }
-
- "All traced signal" should "generate" in {
- class M extends Module {
- val a = Wire(Bool())
- val b = Wire(Vec(2, Bool()))
- a := DontCare
- b := DontCare
- Seq(a, b).foreach(traceName)
- }
- val (_, annos) = compile("NestedModule", () => new M)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[M]
- val allTargets = finalTargetMap(annos)
- allTargets(dut.a.toAbsoluteTarget) should be(Seq(refTarget("M", "a")))
- allTargets(dut.b.toAbsoluteTarget) should be(
- Seq(
- refTarget("M", "b_0"),
- refTarget("M", "b_1")
- )
- )
- allTargets(dut.b(0).toAbsoluteTarget) should be(Seq(refTarget("M", "b_0")))
- allTargets(dut.b(1).toAbsoluteTarget) should be(Seq(refTarget("M", "b_1")))
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/Tuple.scala b/src/test/scala/chiselTests/experimental/Tuple.scala
deleted file mode 100644
index b57766e7..00000000
--- a/src/test/scala/chiselTests/experimental/Tuple.scala
+++ /dev/null
@@ -1,163 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.experimental.conversions._
-import chisel3.stage.ChiselStage
-
-class TupleSpec extends ChiselFlatSpec {
-
- behavior.of("Tuple")
-
- it should "enable using Tuple2 like Data" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val y, z = IO(Output(UInt(8.W)))
- (y, z) := Mux(sel, (a, b), (c, d))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign y = sel ? a : c;")
- verilog should include("assign z = sel ? b : d;")
- }
-
- it should "support nesting of tuples" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val w, x, y, z = IO(Output(UInt(8.W)))
- ((w, x), (y, z)) := ((a, b), (c, d))
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("w <= a")
- chirrtl should include("x <= b")
- chirrtl should include("y <= c")
- chirrtl should include("z <= d")
- }
-
- it should "enable using Tuple3 like Data" in {
- class MyModule extends Module {
- val a, b, c = IO(Input(UInt(8.W)))
- val f, g, h = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val v, w, x = IO(Output(UInt(8.W)))
- (v, w, x) := Mux(sel, (a, b, c), (f, g, h))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign v = sel ? a : f;")
- verilog should include("assign w = sel ? b : g;")
- verilog should include("assign x = sel ? c : h;")
- }
-
- it should "enable using Tuple4 like Data" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val f, g, h, i = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val v, w, x, y = IO(Output(UInt(8.W)))
- (v, w, x, y) := Mux(sel, (a, b, c, d), (f, g, h, i))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign v = sel ? a : f;")
- verilog should include("assign w = sel ? b : g;")
- verilog should include("assign x = sel ? c : h;")
- verilog should include("assign y = sel ? d : i;")
- }
-
- it should "enable using Tuple5 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4) := Mux(sel, (a0, a1, a2, a3, a4), (b0, b1, b2, b3, b4))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 5) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple6 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5) := Mux(sel, (a0, a1, a2, a3, a4, a5), (b0, b1, b2, b3, b4, b5))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 6) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple7 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6) := Mux(sel, (a0, a1, a2, a3, a4, a5, a6), (b0, b1, b2, b3, b4, b5, b6))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 7) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple8 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6, a7 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6, b7 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6, z7 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6, z7) := Mux(sel, (a0, a1, a2, a3, a4, a5, a6, a7), (b0, b1, b2, b3, b4, b5, b6, b7))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 8) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple9 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6, a7, a8 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6, b7, b8 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6, z7, z8 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6, z7, z8) :=
- Mux(sel, (a0, a1, a2, a3, a4, a5, a6, a7, a8), (b0, b1, b2, b3, b4, b5, b6, b7, b8))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 9) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple10 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6, b7, b8, b9 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6, z7, z8, z9) :=
- Mux(sel, (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9), (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 10) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala
deleted file mode 100644
index ec71fe09..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import _root_.firrtl.annotations._
-import chisel3.experimental.{annotate, BaseModule}
-import chisel3.{Data, MemBase}
-import chisel3.experimental.hierarchy.{Definition, Hierarchy, Instance}
-
-// These annotations exist purely for testing purposes
-private[hierarchy] object Annotations {
- case class MarkAnnotation(target: IsMember, tag: String) extends SingleTargetAnnotation[IsMember] {
- def duplicate(n: IsMember): Annotation = this.copy(target = n)
- }
- case class MarkChiselHierarchyAnnotation[B <: BaseModule](d: Hierarchy[B], tag: String, isAbsolute: Boolean)
- extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = MarkAnnotation(d.toTarget, tag)
- }
- case class MarkChiselAnnotation(d: Data, tag: String, isAbsolute: Boolean)
- extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = if (isAbsolute) MarkAnnotation(d.toAbsoluteTarget, tag) else MarkAnnotation(d.toTarget, tag)
- }
- case class MarkChiselMemAnnotation[T <: Data](m: MemBase[T], tag: String, isAbsolute: Boolean)
- extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = if (isAbsolute) MarkAnnotation(m.toAbsoluteTarget, tag) else MarkAnnotation(m.toTarget, tag)
- }
- def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false))
- def mark[T <: Data](d: MemBase[T], tag: String): Unit = annotate(MarkChiselMemAnnotation(d, tag, false))
- def mark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true))
- def amark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, true))
- def amark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true))
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
deleted file mode 100644
index 6ff4a3eb..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
+++ /dev/null
@@ -1,599 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-package experimental.hierarchy
-
-import chisel3._
-import chisel3.experimental.BaseModule
-import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance}
-
-// TODO/Notes
-// - In backport, clock/reset are not automatically assigned. I think this is fixed in 3.5
-// - CircuitTarget for annotations on the definition are wrong - needs to be fixed.
-class DefinitionSpec extends ChiselFunSpec with Utils {
- import Annotations._
- import Examples._
- describe("0: Definition instantiation") {
- it("0.0: module name of a definition should be correct") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOne :")
- }
- it("0.2: accessing internal fields through non-generated means is hard to do") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- //definition.lookup(_.in) // Uncommenting this line will give the following error:
- //"You are trying to access a macro-only API. Please use the @public annotation instead."
- definition.in
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOne :")
- }
- it("0.2: reset inference is not defaulted to Bool for definitions") {
- class Top extends Module with RequireAsyncReset {
- val definition = Definition(new HasUninferredReset)
- val i0 = Instance(definition)
- i0.in := 0.U
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of HasUninferredReset")
- }
- it("0.3: module names of repeated definition should be sequential") {
- class Top extends Module {
- val k = Module(
- new AddTwoParameterized(
- 4,
- (x: Int) =>
- Seq.tabulate(x) { j =>
- val addOneDef = Definition(new AddOneParameterized(x + j))
- val addOne = Instance(addOneDef)
- addOne
- }
- )
- )
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOneParameterized :")
- chirrtl.serialize should include("module AddOneParameterized_1 :")
- chirrtl.serialize should include("module AddOneParameterized_2 :")
- chirrtl.serialize should include("module AddOneParameterized_3 :")
- }
- it("0.4: multiple instantiations should have sequential names") {
- class Top extends Module {
- val addOneDef = Definition(new AddOneParameterized(4))
- val addOne = Instance(addOneDef)
- val otherAddOne = Module(new AddOneParameterized(4))
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOneParameterized :")
- chirrtl.serialize should include("module AddOneParameterized_1 :")
- }
- it("0.5: nested definitions should have sequential names") {
- class Top extends Module {
- val k = Module(
- new AddTwoWithNested(
- 4,
- (x: Int) =>
- Seq.tabulate(x) { j =>
- val addOneDef = Definition(new AddOneWithNested(x + j))
- val addOne = Instance(addOneDef)
- addOne
- }
- )
- )
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOneWithNested :")
- chirrtl.serialize should include("module AddOneWithNested_1 :")
- chirrtl.serialize should include("module AddOneWithNested_2 :")
- chirrtl.serialize should include("module AddOneWithNested_3 :")
- }
- }
- describe("1: Annotations on definitions in same chisel compilation") {
- it("1.0: should work on a single definition, annotating the definition") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- mark(definition, "mark")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne".mt, "mark"))
- }
- it("1.1: should work on a single definition, annotating an inner wire") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- mark(definition.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne>innerWire".rt, "i0.innerWire"))
- }
- it("1.2: should work on a two nested definitions, annotating the definition") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- mark(definition.definition, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne".mt, "i0.i0"))
- }
- it("1.2: should work on an instance in a definition, annotating the instance") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- mark(definition.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne".it, "i0.i0"))
- }
- it("1.2: should work on a definition in an instance, annotating the definition") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- val i0 = Instance(definition)
- mark(i0.definition, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne".mt, "i0.i0"))
- }
- it("1.3: should work on a wire in an instance in a definition") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- mark(definition.i0.innerWire, "i0.i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "i0.i0.innerWire"))
- }
- it("1.4: should work on a nested module in a definition, annotating the module") {
- class Top extends Module {
- val definition: Definition[AddTwoMixedModules] = Definition(new AddTwoMixedModules)
- mark(definition.i1, "i0.i1")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_1".it, "i0.i1"))
- }
- // Can you define an instantiable container? I think not.
- // Instead, we can test the instantiable container in a definition
- it("1.5: should work on an instantiable container, annotating a wire in the defintion") {
- class Top extends Module {
- val definition: Definition[AddOneWithInstantiableWire] = Definition(new AddOneWithInstantiableWire)
- mark(definition.wireContainer.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableWire>innerWire".rt, "i0.innerWire"))
- }
- it("1.6: should work on an instantiable container, annotating a module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableModule)
- mark(definition.moduleContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableModule/i0:AddOne".it, "i0.i0"))
- }
- it("1.7: should work on an instantiable container, annotating an instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstance)
- mark(definition.instanceContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstance/i0:AddOne".it, "i0.i0"))
- }
- it("1.8: should work on an instantiable container, annotating an instantiable container's module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- mark(definition.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.9: should work on public member which references public member of another instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- mark(definition.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.10: should work for targets on definition to have correct circuit name") {
- class Top extends Module {
- val definition = Definition(new AddOneWithAnnotation)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithAnnotation>innerWire".rt, "innerWire"))
- }
- }
- describe("2: Annotations on designs not in the same chisel compilation") {
- it("2.0: should work on an innerWire, marked in a different compilation") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Definition(new ViewerParent(x, false, true))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "first"))
- }
- it("2.1: should work on an innerWire, marked in a different compilation, in instanced instantiable") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Definition(new ViewerParent(x, true, false))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "second"))
- }
- it("2.2: should work on an innerWire, marked in a different compilation, in instanced module") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Definition(new ViewerParent(x, false, false))
- mark(parent.viewer.x.i0.innerWire, "third")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "third"))
- }
- }
- describe("3: @public") {
- it("3.0: should work on multi-vals") {
- class Top() extends Module {
- val mv = Definition(new MultiVal())
- mark(mv.x, "mv.x")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|MultiVal>x".rt, "mv.x"))
- }
- it("3.1: should work on lazy vals") {
- class Top() extends Module {
- val lv = Definition(new LazyVal())
- mark(lv.x, lv.y)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|LazyVal>x".rt, "Hi"))
- }
- it("3.2: should work on islookupables") {
- class Top() extends Module {
- val p = Parameters("hi", 0)
- val up = Definition(new UsesParameters(p))
- mark(up.x, up.y.string + up.y.int)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|UsesParameters>x".rt, "hi0"))
- }
- it("3.3: should work on lists") {
- class Top() extends Module {
- val i = Definition(new HasList())
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasList>x_1".rt, "2"))
- }
- it("3.4: should work on seqs") {
- class Top() extends Module {
- val i = Definition(new HasSeq())
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasSeq>x_1".rt, "2"))
- }
- it("3.5: should work on options") {
- class Top() extends Module {
- val i = Definition(new HasOption())
- i.x.map(x => mark(x, "x"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasOption>x".rt, "x"))
- }
- it("3.6: should work on vecs") {
- class Top() extends Module {
- val i = Definition(new HasVec())
- mark(i.x, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasVec>x".rt, "blah"))
- }
- it("3.7: should work on statically indexed vectors external to module") {
- class Top() extends Module {
- val i = Definition(new HasVec())
- mark(i.x(1), "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasVec>x[1]".rt, "blah"))
- }
- it("3.8: should work on statically indexed vectors internal to module") {
- class Top() extends Module {
- val i = Definition(new HasIndexedVec())
- mark(i.y, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasIndexedVec>x[1]".rt, "blah"))
- }
- ignore("3.9: should work on vals in constructor arguments") {
- class Top() extends Module {
- val i = Definition(new HasPublicConstructorArgs(10))
- //mark(i.x, i.int.toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasPublicConstructorArgs>x".rt, "10"))
- }
- it("3.10: should work on unimplemented vals in abstract classes/traits") {
- class Top() extends Module {
- val i = Definition(new ConcreteHasBlah())
- def f(d: Definition[HasBlah]): Unit = {
- mark(d, d.blah.toString)
- }
- f(i)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|ConcreteHasBlah".mt, "10"))
- }
- it("3.11: should work on eithers") {
- class Top() extends Module {
- val i = Definition(new HasEither())
- i.x.map(x => mark(x, "xright")).left.map(x => mark(x, "xleft"))
- i.y.map(x => mark(x, "yright")).left.map(x => mark(x, "yleft"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasEither>x".rt, "xright"))
- annos should contain(MarkAnnotation("~Top|HasEither>y".rt, "yleft"))
- }
- it("3.12: should work on tuple2") {
- class Top() extends Module {
- val i = Definition(new HasTuple2())
- mark(i.xy._1, "x")
- mark(i.xy._2, "y")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasTuple2>x".rt, "x"))
- annos should contain(MarkAnnotation("~Top|HasTuple2>y".rt, "y"))
- }
- it("3.13: should work on Mems/SyncReadMems") {
- class Top() extends Module {
- val i = Definition(new HasMems())
- mark(i.mem, "Mem")
- mark(i.syncReadMem, "SyncReadMem")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasMems>mem".rt, "Mem"))
- annos should contain(MarkAnnotation("~Top|HasMems>syncReadMem".rt, "SyncReadMem"))
- }
- it("3.14: should not create memory ports") {
- class Top() extends Module {
- val i = Definition(new HasMems())
- i.mem(0) := 100.U // should be illegal!
- }
- val failure = intercept[ChiselException] {
- getFirrtlAndAnnos(new Top)
- }
- assert(
- failure.getMessage ==
- "Cannot create a memory port in a different module (Top) than where the memory is (HasMems)."
- )
- }
- }
- describe("4: toDefinition") {
- it("4.0: should work on modules") {
- class Top() extends Module {
- val i = Module(new AddOne())
- f(i.toDefinition)
- }
- def f(i: Definition[AddOne]): Unit = mark(i.innerWire, "blah")
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on seqs of modules") {
- class Top() extends Module {
- val is = Seq(Module(new AddTwo()), Module(new AddTwo())).map(_.toDefinition)
- mark(f(is), "blah")
- }
- def f(i: Seq[Definition[AddTwo]]): Data = i.head.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on options of modules") {
- class Top() extends Module {
- val is: Option[Definition[AddTwo]] = Some(Module(new AddTwo())).map(_.toDefinition)
- mark(f(is), "blah")
- }
- def f(i: Option[Definition[AddTwo]]): Data = i.get.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- }
- describe("5: Absolute Targets should work as expected") {
- it("5.0: toAbsoluteTarget on a port of a definition") {
- class Top() extends Module {
- val i = Definition(new AddTwo())
- amark(i.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo>in".rt, "blah"))
- }
- it("5.1: toAbsoluteTarget on a subinstance's data within a definition") {
- class Top() extends Module {
- val i = Definition(new AddTwo())
- amark(i.i0.innerWire, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("5.2: toAbsoluteTarget on a submodule's data within a definition") {
- class Top() extends Module {
- val i = Definition(new AddTwoMixedModules())
- amark(i.i1.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_1>in".rt, "blah"))
- }
- it("5.3: toAbsoluteTarget on a submodule's data, in an aggregate, within a definition") {
- class Top() extends Module {
- val i = Definition(new InstantiatesHasVec())
- amark(i.i1.x.head, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|InstantiatesHasVec/i1:HasVec_1>x[0]".rt, "blah"))
- }
- }
- describe("6: @instantiable traits should work as expected") {
- class MyBundle extends Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- }
- @instantiable
- trait ModuleIntf extends BaseModule {
- @public val io = IO(new MyBundle)
- }
- @instantiable
- class ModuleWithCommonIntf(suffix: String = "") extends Module with ModuleIntf {
- override def desiredName: String = super.desiredName + suffix
- @public val sum = io.in + 1.U
-
- io.out := sum
- }
- class BlackBoxWithCommonIntf extends BlackBox with ModuleIntf
-
- it("6.0: A Module that implements an @instantiable trait should be definable as that trait") {
- class Top extends Module {
- val i: Definition[ModuleIntf] = Definition(new ModuleWithCommonIntf)
- mark(i.io.in, "gotcha")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|ModuleWithCommonIntf".mt -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it(
- "6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both"
- ) {
- class Top extends Module {
- val i: Definition[ModuleWithCommonIntf] = Definition(new ModuleWithCommonIntf)
- mark(i.io.in, "gotcha")
- mark(i.sum, "also this")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|ModuleWithCommonIntf>sum".rt -> "also this",
- "~Top|ModuleWithCommonIntf".mt -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.2 A BlackBox that implements an @instantiable trait should be instantiable as that trait") {
- class Top extends Module {
- val m: ModuleIntf = Module(new BlackBoxWithCommonIntf)
- val d: Definition[ModuleIntf] = m.toDefinition
- mark(d.io.in, "gotcha")
- mark(d, "module")
- }
- val expected = List(
- "~Top|BlackBoxWithCommonIntf>in".rt -> "gotcha",
- "~Top|BlackBoxWithCommonIntf".mt -> "module"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.3 It should be possible to have Vectors of @instantiable traits mixing concrete subclasses") {
- class Top extends Module {
- val definition = Definition(new ModuleWithCommonIntf("X"))
- val insts: Seq[Definition[ModuleIntf]] = Vector(
- Module(new ModuleWithCommonIntf("Y")).toDefinition,
- Module(new BlackBoxWithCommonIntf).toDefinition,
- definition
- )
- mark(insts(0).io.in, "foo")
- mark(insts(1).io.in, "bar")
- mark(insts(2).io.in, "fizz")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntfY>io.in".rt -> "foo",
- "~Top|BlackBoxWithCommonIntf>in".rt -> "bar",
- "~Top|ModuleWithCommonIntfX>io.in".rt -> "fizz"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
- describe("7: @instantiable and @public should compose with DataView") {
- import chisel3.experimental.dataview._
- ignore("7.0: should work on simple Views") {
- @instantiable
- class MyModule extends RawModule {
- val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- val sum = in + 1.U
- out := sum + 1.U
- @public val foo = in.viewAs[UInt]
- @public val bar = sum.viewAs[UInt]
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val d = Definition(new MyModule)
- val i = Instance(d)
- i.foo := foo
- bar := i.out
- mark(d.out, "out")
- mark(d.foo, "foo")
- mark(d.bar, "bar")
- }
- val expectedAnnos = List(
- "~Top|MyModule>out".rt -> "out",
- "~Top|MyModule>in".rt -> "foo",
- "~Top|MyModule>sum".rt -> "bar"
- )
- val expectedLines = List(
- "i.in <= foo",
- "bar <= i.out"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- ignore("7.1: should work on Aggregate Views that are mapped 1:1") {
- import chiselTests.experimental.SimpleBundleDataView._
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Input(new BundleA(8)))
- private val b = IO(Output(new BundleA(8)))
- @public val in = a.viewAs[BundleB]
- @public val out = b.viewAs[BundleB]
- out := in
- }
- class Top extends RawModule {
- val foo = IO(Input(new BundleB(8)))
- val bar = IO(Output(new BundleB(8)))
- val d = Definition(new MyModule)
- val i = Instance(d)
- i.in := foo
- bar.bar := i.out.bar
- mark(d.in, "in")
- mark(d.in.bar, "in_bar")
- }
- val expectedAnnos = List(
- "~Top|MyModule>a".rt -> "in",
- "~Top|MyModule>a.foo".rt -> "in_bar"
- )
- val expectedLines = List(
- "i.a <= foo",
- "bar <= i.b.foo"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
deleted file mode 100644
index 27725c49..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
+++ /dev/null
@@ -1,340 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import chisel3._
-import chisel3.util.Valid
-import chisel3.experimental.hierarchy._
-import chisel3.experimental.BaseModule
-
-object Examples {
- import Annotations._
- @instantiable
- class AddOne extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val innerWire = Wire(UInt(32.W))
- innerWire := in + 1.U
- out := innerWire
- }
- @instantiable
- class AddOneWithAnnotation extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val innerWire = Wire(UInt(32.W))
- mark(innerWire, "innerWire")
- innerWire := in + 1.U
- out := innerWire
- }
- @instantiable
- class AddOneWithAbsoluteAnnotation extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val innerWire = Wire(UInt(32.W))
- amark(innerWire, "innerWire")
- innerWire := in + 1.U
- out := innerWire
- }
- @instantiable
- class AddOneParameterized(width: Int) extends Module {
- @public val in = IO(Input(UInt(width.W)))
- @public val out = IO(Output(UInt(width.W)))
- out := in + 1.U
- }
- class AddOneWithNested(width: Int) extends Module {
- @public val in = IO(Input(UInt(width.W)))
- @public val out = IO(Output(UInt(width.W)))
- val addOneDef = Seq.fill(3)(Definition(new AddOne))
- out := in + 1.U
- }
- @instantiable
- class AddOneBlackBox extends BlackBox {
- @public val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- }
-
- @instantiable
- class AddTwo extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val definition = Definition(new AddOne)
- @public val i0: Instance[AddOne] = Instance(definition)
- @public val i1: Instance[AddOne] = Instance(definition)
- i0.in := in
- i1.in := i0.out
- out := i1.out
- }
- @instantiable
- class AddTwoMixedModules extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- val definition = Definition(new AddOne)
- @public val i0: Instance[AddOne] = Instance(definition)
- @public val i1 = Module(new AddOne)
- i0.in := in
- i1.in := i0.out
- out := i1.out
- }
- @instantiable
- class AddTwoParameterized(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneParameterized]])
- extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
- val addOnes = makeParameterizedOnes(width)
- addOnes.head.in := in
- out := addOnes.last.out
- addOnes.zip(addOnes.tail).foreach { case (head, tail) => tail.in := head.out }
- }
- @instantiable
- class AddTwoWithNested(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneWithNested]]) extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
- val addOnes = makeParameterizedOnes(width)
- }
-
- @instantiable
- class AddFour extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val definition = Definition(new AddTwoMixedModules)
- @public val i0 = Instance(definition)
- @public val i1 = Instance(definition)
- i0.in := in
- i1.in := i0.out
- out := i1.out
- }
- @instantiable
- class AggregatePortModule extends Module {
- @public val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- io.out := io.in
- }
- @instantiable
- class WireContainer {
- @public val innerWire = Wire(UInt(32.W))
- }
- @instantiable
- class AddOneWithInstantiableWire extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val wireContainer = new WireContainer()
- wireContainer.innerWire := in + 1.U
- out := wireContainer.innerWire
- }
- @instantiable
- class AddOneContainer {
- @public val i0 = Module(new AddOne)
- }
- @instantiable
- class AddOneWithInstantiableModule extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val moduleContainer = new AddOneContainer()
- moduleContainer.i0.in := in
- out := moduleContainer.i0.out
- }
- @instantiable
- class AddOneInstanceContainer {
- val definition = Definition(new AddOne)
- @public val i0 = Instance(definition)
- }
- @instantiable
- class AddOneWithInstantiableInstance extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val instanceContainer = new AddOneInstanceContainer()
- instanceContainer.i0.in := in
- out := instanceContainer.i0.out
- }
- @instantiable
- class AddOneContainerContainer {
- @public val container = new AddOneContainer
- }
- @instantiable
- class AddOneWithInstantiableInstantiable extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val containerContainer = new AddOneContainerContainer()
- containerContainer.container.i0.in := in
- out := containerContainer.container.i0.out
- }
- @instantiable
- class Viewer(val y: AddTwo, markPlease: Boolean) {
- @public val x = y
- if (markPlease) mark(x.i0.innerWire, "first")
- }
- @instantiable
- class ViewerParent(val x: AddTwo, markHere: Boolean, markThere: Boolean) extends Module {
- @public val viewer = new Viewer(x, markThere)
- if (markHere) mark(viewer.x.i0.innerWire, "second")
- }
- @instantiable
- class MultiVal() extends Module {
- @public val (x, y) = (Wire(UInt(3.W)), Wire(UInt(3.W)))
- }
- @instantiable
- class LazyVal() extends Module {
- @public val x = Wire(UInt(3.W))
- @public lazy val y = "Hi"
- }
- case class Parameters(string: String, int: Int) extends IsLookupable
- @instantiable
- class UsesParameters(p: Parameters) extends Module {
- @public val y = p
- @public val x = Wire(UInt(3.W))
- }
- @instantiable
- class HasList() extends Module {
- @public val y = List(1, 2, 3)
- @public val x = List.fill(3)(Wire(UInt(3.W)))
- }
- @instantiable
- class HasSeq() extends Module {
- @public val y = Seq(1, 2, 3)
- @public val x = Seq.fill(3)(Wire(UInt(3.W)))
- }
- @instantiable
- class HasOption() extends Module {
- @public val x: Option[UInt] = Some(Wire(UInt(3.W)))
- }
- @instantiable
- class HasEither() extends Module {
- @public val x: Either[Bool, UInt] = Right(Wire(UInt(3.W)).suggestName("x"))
- @public val y: Either[Bool, UInt] = Left(Wire(Bool()).suggestName("y"))
- }
- @instantiable
- class HasTuple2() extends Module {
- val x = Wire(UInt(3.W))
- val y = Wire(Bool())
- @public val xy = (x, y)
- }
- @instantiable
- class HasVec() extends Module {
- @public val x = VecInit(1.U, 2.U, 3.U)
- }
- @instantiable
- class HasIndexedVec() extends Module {
- val x = VecInit(1.U, 2.U, 3.U)
- @public val y = x(1)
- }
- @instantiable
- class HasSubFieldAccess extends Module {
- val in = IO(Input(Valid(UInt(8.W))))
- @public val valid = in.valid
- @public val bits = in.bits
- }
- @instantiable
- class HasPublicConstructorArgs(@public val int: Int) extends Module {
- @public val x = Wire(UInt(3.W))
- }
- @instantiable
- class InstantiatesHasVec() extends Module {
- @public val i0 = Instance(Definition(new HasVec()))
- @public val i1 = Module(new HasVec())
- }
- @instantiable
- class HasUninferredReset() extends Module {
- @public val in = IO(Input(UInt(3.W)))
- @public val out = IO(Output(UInt(3.W)))
- out := RegNext(in)
- }
- @instantiable
- abstract class HasBlah() extends Module {
- @public val blah: Int
- }
-
- @instantiable
- class ConcreteHasBlah() extends HasBlah {
- val blah = 10
- }
- @instantiable
- class HasTypeParams[D <: Data](d: D) extends Module {
- @public val blah = Wire(d)
- }
-
- @instantiable
- class HasMultipleTypeParamsInside extends Module {
- val tpDef0 = Definition(new HasTypeParams(Bool()))
- val tpDef1 = Definition(new HasTypeParams(UInt(4.W)))
- val i00 = Instance(tpDef0)
- val i01 = Instance(tpDef0)
- val i10 = Instance(tpDef1)
- val i11 = Instance(tpDef1)
- }
-
- @instantiable
- class HasMems() extends Module {
- @public val mem = Mem(8, UInt(32.W))
- @public val syncReadMem = SyncReadMem(8, UInt(32.W))
- }
-
- @instantiable
- class LeafInstantiable(val bundle: Data) {
- @public val bundle = bundle
- }
-
- @instantiable
- class NestedInstantiable(val in: LeafInstantiable, val out: LeafInstantiable) {
- @public val in = in
- @public val out = out
- }
-
- @instantiable
- class AddOneNestedInstantiableData(width: Int) extends Module {
- @public val in = IO(Input(UInt(width.W)))
- @public val out = IO(Output(UInt(width.W)))
- out := in + 1.U
-
- @public val leafOut = new LeafInstantiable(out)
- @public val leafIn = new LeafInstantiable(in)
- @public val nested = new NestedInstantiable(in = leafIn, out = leafOut)
-
- }
-
- class AddTwoNestedInstantiableData(width: Int) extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
- val addOneDef = Definition(new AddOneNestedInstantiableData(width))
- val i0 = Instance(addOneDef)
- val i1 = Instance(addOneDef)
- i0.in := in
- i1.in := i0.out
- out := i1.out
-
- // both are equivalent to the above
- i1.leafIn.bundle := i0.leafOut.bundle
- i1.nested.in.bundle := i0.nested.out.bundle
- }
-
- class AddTwoNestedInstantiableDataSubmodule(addOneDef: Definition[AddOneNestedInstantiableData]) extends Module {
- val in = IO(Input(UInt(addOneDef.in.getWidth.W)))
- val out = IO(Output(UInt(addOneDef.out.getWidth.W)))
- val i0 = Instance(addOneDef)
- val i1 = Instance(addOneDef)
- i0.in := in
- i1.in := i0.out
- out := i1.out
-
- // both are equivalent to the above
- i1.leafIn.bundle := i0.leafOut.bundle
- i1.nested.in.bundle := i0.nested.out.bundle
- }
-
- class AddTwoNestedInstantiableDataWrapper(width: Int) extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
-
- val original = Module(new AddOneNestedInstantiableData(width))
- val copy = Module(new AddTwoNestedInstantiableDataSubmodule(original.toDefinition))
-
- original.in := in
- copy.in := original.out
- out := copy.out
-
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
deleted file mode 100644
index 6596cd51..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
+++ /dev/null
@@ -1,1146 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-package experimental.hierarchy
-
-import chisel3._
-import chisel3.experimental.BaseModule
-import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance}
-import chisel3.util.{DecoupledIO, Valid}
-
-// TODO/Notes
-// - In backport, clock/reset are not automatically assigned. I think this is fixed in 3.5
-// - CircuitTarget for annotations on the definition are wrong - needs to be fixed.
-class InstanceSpec extends ChiselFunSpec with Utils {
- import Annotations._
- import Examples._
- describe("0: Instance instantiation") {
- it("0.0: name of an instance should be correct") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- val i0 = Instance(definition)
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of AddOne")
- }
- it("0.1: name of an instanceclone should not error") {
- class Top extends Module {
- val definition = Definition(new AddTwo)
- val i0 = Instance(definition)
- val i = i0.i0 // This should not error
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of AddTwo")
- }
- it("0.2: accessing internal fields through non-generated means is hard to do") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- val i0 = Instance(definition)
- //i0.lookup(_.in) // Uncommenting this line will give the following error:
- //"You are trying to access a macro-only API. Please use the @public annotation instead."
- i0.in
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of AddOne")
- }
- it("0.3: BlackBoxes should be supported") {
- class Top extends Module {
- val in = IO(Input(UInt(32.W)))
- val out = IO(Output(UInt(32.W)))
- val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- val definition = Definition(new AddOneBlackBox)
- val i0 = Instance(definition)
- val i1 = Instance(definition)
- i0.io.in := in
- out := i0.io.out
- io <> i1.io
- }
- val chirrtl = getFirrtlAndAnnos(new Top)._1.serialize
- chirrtl should include("inst i0 of AddOneBlackBox")
- chirrtl should include("inst i1 of AddOneBlackBox")
- chirrtl should include("i0.in <= in")
- chirrtl should include("out <= i0.out")
- chirrtl should include("i1.in <= io.in")
- chirrtl should include("io.out <= i1.out")
- }
- }
- describe("1: Annotations on instances in same chisel compilation") {
- it("1.0: should work on a single instance, annotating the instance") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- val i0: Instance[AddOne] = Instance(definition)
- mark(i0, "i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOne".it, "i0"))
- }
- it("1.1: should work on a single instance, annotating an inner wire") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- val i0: Instance[AddOne] = Instance(definition)
- mark(i0.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOne>innerWire".rt, "i0.innerWire"))
- }
- it("1.2: should work on a two nested instances, annotating the instance") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- val i0: Instance[AddTwo] = Instance(definition)
- mark(i0.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne".it, "i0.i0"))
- }
- it("1.3: should work on a two nested instances, annotating the inner wire") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- val i0: Instance[AddTwo] = Instance(definition)
- mark(i0.i0.innerWire, "i0.i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne>innerWire".rt, "i0.i0.innerWire"))
- }
- it("1.4: should work on a nested module in an instance, annotating the module") {
- class Top extends Module {
- val definition: Definition[AddTwoMixedModules] = Definition(new AddTwoMixedModules)
- val i0: Instance[AddTwoMixedModules] = Instance(definition)
- mark(i0.i1, "i0.i1")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddTwoMixedModules/i1:AddOne_1".it, "i0.i1"))
- }
- it("1.5: should work on an instantiable container, annotating a wire") {
- class Top extends Module {
- val definition: Definition[AddOneWithInstantiableWire] = Definition(new AddOneWithInstantiableWire)
- val i0: Instance[AddOneWithInstantiableWire] = Instance(definition)
- mark(i0.wireContainer.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableWire>innerWire".rt, "i0.innerWire"))
- }
- it("1.6: should work on an instantiable container, annotating a module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableModule)
- val i0 = Instance(definition)
- mark(i0.moduleContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableModule/i0:AddOne".it, "i0.i0"))
- }
- it("1.7: should work on an instantiable container, annotating an instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstance)
- val i0 = Instance(definition)
- mark(i0.instanceContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstance/i0:AddOne".it, "i0.i0"))
- }
- it("1.8: should work on an instantiable container, annotating an instantiable container's module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- val i0 = Instance(definition)
- mark(i0.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.9: should work on public member which references public member of another instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- val i0 = Instance(definition)
- mark(i0.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.10: should work for targets on definition to have correct circuit name") {
- class Top extends Module {
- val definition = Definition(new AddOneWithAnnotation)
- val i0 = Instance(definition)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithAnnotation>innerWire".rt, "innerWire"))
- }
- it("1.11: should work on things with type parameters") {
- class Top extends Module {
- val definition = Definition(new HasTypeParams[UInt](UInt(3.W)))
- val i0 = Instance(definition)
- mark(i0.blah, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:HasTypeParams>blah".rt, "blah"))
- }
- }
- describe("2: Annotations on designs not in the same chisel compilation") {
- it("2.0: should work on an innerWire, marked in a different compilation") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Instance(Definition(new ViewerParent(x, false, true)))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "first"))
- }
- it("2.1: should work on an innerWire, marked in a different compilation, in instanced instantiable") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Instance(Definition(new ViewerParent(x, true, false)))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "second"))
- }
- it("2.2: should work on an innerWire, marked in a different compilation, in instanced module") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Instance(Definition(new ViewerParent(x, false, false)))
- mark(parent.viewer.x.i0.innerWire, "third")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "third"))
- }
- }
- describe("3: @public") {
- it("3.0: should work on multi-vals") {
- class Top() extends Module {
- val mv = Instance(Definition(new MultiVal()))
- mark(mv.x, "mv.x")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/mv:MultiVal>x".rt, "mv.x"))
- }
- it("3.1: should work on lazy vals") {
- class Top() extends Module {
- val lv = Instance(Definition(new LazyVal()))
- mark(lv.x, lv.y)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/lv:LazyVal>x".rt, "Hi"))
- }
- it("3.2: should work on islookupables") {
- class Top() extends Module {
- val p = Parameters("hi", 0)
- val up = Instance(Definition(new UsesParameters(p)))
- mark(up.x, up.y.string + up.y.int)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/up:UsesParameters>x".rt, "hi0"))
- }
- it("3.3: should work on lists") {
- class Top() extends Module {
- val i = Instance(Definition(new HasList()))
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasList>x_1".rt, "2"))
- }
- it("3.4: should work on seqs") {
- class Top() extends Module {
- val i = Instance(Definition(new HasSeq()))
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasSeq>x_1".rt, "2"))
- }
- it("3.5: should work on options") {
- class Top() extends Module {
- val i = Instance(Definition(new HasOption()))
- i.x.map(x => mark(x, "x"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasOption>x".rt, "x"))
- }
- it("3.6: should work on vecs") {
- class Top() extends Module {
- val i = Instance(Definition(new HasVec()))
- mark(i.x, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasVec>x".rt, "blah"))
- }
- it("3.7: should work on statically indexed vectors external to module") {
- class Top() extends Module {
- val i = Instance(Definition(new HasVec()))
- mark(i.x(1), "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasVec>x[1]".rt, "blah"))
- }
- it("3.8: should work on statically indexed vectors internal to module") {
- class Top() extends Module {
- val i = Instance(Definition(new HasIndexedVec()))
- mark(i.y, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasIndexedVec>x[1]".rt, "blah"))
- }
- it("3.9: should work on accessed subfields of aggregate ports") {
- class Top extends Module {
- val input = IO(Input(Valid(UInt(8.W))))
- val i = Instance(Definition(new HasSubFieldAccess))
- i.valid := input.valid
- i.bits := input.bits
- mark(i.valid, "valid")
- mark(i.bits, "bits")
- }
- val expected = List(
- "~Top|Top/i:HasSubFieldAccess>in.valid".rt -> "valid",
- "~Top|Top/i:HasSubFieldAccess>in.bits".rt -> "bits"
- )
- val lines = List(
- "i.in.valid <= input.valid",
- "i.in.bits <= input.bits"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- lines) {
- text should include(line)
- }
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- ignore("3.10: should work on vals in constructor arguments") {
- class Top() extends Module {
- val i = Instance(Definition(new HasPublicConstructorArgs(10)))
- //mark(i.x, i.int.toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasPublicConstructorArgs>x".rt, "10"))
- }
- it("3.11: should work on eithers") {
- class Top() extends Module {
- val i = Instance(Definition(new HasEither()))
- i.x.map(x => mark(x, "xright")).left.map(x => mark(x, "xleft"))
- i.y.map(x => mark(x, "yright")).left.map(x => mark(x, "yleft"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasEither>x".rt, "xright"))
- annos should contain(MarkAnnotation("~Top|Top/i:HasEither>y".rt, "yleft"))
- }
- it("3.12: should work on tuple2") {
- class Top() extends Module {
- val i = Instance(Definition(new HasTuple2()))
- mark(i.xy._1, "x")
- mark(i.xy._2, "y")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasTuple2>x".rt, "x"))
- annos should contain(MarkAnnotation("~Top|Top/i:HasTuple2>y".rt, "y"))
- }
-
- it("3.13: should properly support val modifiers") {
- class SupClass extends Module {
- val value = 10
- val overriddenVal = 10
- }
- trait SupTrait {
- def x: Int
- def y: Int
- }
- @instantiable class SubClass() extends SupClass with SupTrait {
- // This errors
- //@public private val privateVal = 10
- // This errors
- //@public protected val protectedVal = 10
- @public override val overriddenVal = 12
- @public final val finalVal = 12
- @public lazy val lazyValue = 12
- @public val value = value
- @public final override lazy val x: Int = 3
- @public override final lazy val y: Int = 4
- }
- }
- it("3.13: should work with Mems/SyncReadMems") {
- class Top() extends Module {
- val i = Instance(Definition(new HasMems()))
- mark(i.mem, "Mem")
- mark(i.syncReadMem, "SyncReadMem")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasMems>mem".rt, "Mem"))
- annos should contain(MarkAnnotation("~Top|Top/i:HasMems>syncReadMem".rt, "SyncReadMem"))
- }
- it("(3.p): should make connectable IOs on nested IsInstantiables that have IO Datas in them") {
- val (chirrtl, _) = getFirrtlAndAnnos(new AddTwoNestedInstantiableData(4))
- exactly(3, chirrtl.serialize.split('\n')) should include("i1.in <= i0.out")
- }
- it(
- "(3.q): should make connectable IOs on nested IsInstantiables's Data when the Instance and Definition do not have the same parent"
- ) {
- val (chirrtl, _) = getFirrtlAndAnnos(new AddTwoNestedInstantiableDataWrapper(4))
- exactly(3, chirrtl.serialize.split('\n')) should include("i1.in <= i0.out")
- }
- }
- describe("4: toInstance") {
- it("4.0: should work on modules") {
- class Top() extends Module {
- val i = Module(new AddOne())
- f(i.toInstance)
- }
- def f(i: Instance[AddOne]): Unit = mark(i.innerWire, "blah")
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne>innerWire".rt, "blah"))
- }
- it("4.1: should work on isinstantiables") {
- class Top() extends Module {
- val i = Module(new AddTwo())
- val v = new Viewer(i, false)
- mark(f(v.toInstance), "blah")
- }
- def f(i: Instance[Viewer]): Data = i.x.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on seqs of modules") {
- class Top() extends Module {
- val is = Seq(Module(new AddTwo()), Module(new AddTwo())).map(_.toInstance)
- mark(f(is), "blah")
- }
- def f(i: Seq[Instance[AddTwo]]): Data = i.head.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.3: should work on seqs of isInstantiables") {
- class Top() extends Module {
- val i = Module(new AddTwo())
- val vs = Seq(new Viewer(i, false), new Viewer(i, false)).map(_.toInstance)
- mark(f(vs), "blah")
- }
- def f(i: Seq[Instance[Viewer]]): Data = i.head.x.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on options of modules") {
- class Top() extends Module {
- val is: Option[Instance[AddTwo]] = Some(Module(new AddTwo())).map(_.toInstance)
- mark(f(is), "blah")
- }
- def f(i: Option[Instance[AddTwo]]): Data = i.get.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- }
- describe("5: Absolute Targets should work as expected") {
- it("5.0: toAbsoluteTarget on a port of an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwo()))
- amark(i.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwo>in".rt, "blah"))
- }
- it("5.1: toAbsoluteTarget on a subinstance's data within an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwo()))
- amark(i.i0.innerWire, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("5.2: toAbsoluteTarget on a submodule's data within an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwoMixedModules()))
- amark(i.i1.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwoMixedModules/i1:AddOne_1>in".rt, "blah"))
- }
- it("5.3: toAbsoluteTarget on a submodule's data, in an aggregate, within an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new InstantiatesHasVec()))
- amark(i.i1.x.head, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_1>x[0]".rt, "blah"))
- }
- it("5.4: toAbsoluteTarget on a submodule's data, in an aggregate, within an instance, ILit") {
- class MyBundle extends Bundle { val x = UInt(3.W) }
- @instantiable
- class HasVec() extends Module {
- @public val x = Wire(Vec(3, new MyBundle()))
- }
- @instantiable
- class InstantiatesHasVec() extends Module {
- @public val i0 = Instance(Definition(new HasVec()))
- @public val i1 = Module(new HasVec())
- }
- class Top() extends Module {
- val i = Instance(Definition(new InstantiatesHasVec()))
- amark(i.i1.x.head.x, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_1>x[0].x".rt, "blah"))
- }
- it("5.5: toAbsoluteTarget on a subinstance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwo()))
- amark(i.i1, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwo/i1:AddOne".it, "blah"))
- }
- it("5.6: should work for absolute targets on definition to have correct circuit name") {
- class Top extends Module {
- val definition = Definition(new AddOneWithAbsoluteAnnotation)
- val i0 = Instance(definition)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithAbsoluteAnnotation>innerWire".rt, "innerWire"))
- }
- }
- describe("6: @instantiable traits should work as expected") {
- class MyBundle extends Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- }
- @instantiable
- trait ModuleIntf extends BaseModule {
- @public val io = IO(new MyBundle)
- }
- @instantiable
- class ModuleWithCommonIntf(suffix: String = "") extends Module with ModuleIntf {
- override def desiredName: String = super.desiredName + suffix
- @public val sum = io.in + 1.U
-
- io.out := sum
- }
- class BlackBoxWithCommonIntf extends BlackBox with ModuleIntf
-
- it("6.0: A Module that implements an @instantiable trait should be instantiable as that trait") {
- class Top extends Module {
- val i: Instance[ModuleIntf] = Instance(Definition(new ModuleWithCommonIntf))
- mark(i.io.in, "gotcha")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|Top/i:ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|Top/i:ModuleWithCommonIntf".it -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it(
- "6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both"
- ) {
- class Top extends Module {
- val i: Instance[ModuleWithCommonIntf] = Instance(Definition(new ModuleWithCommonIntf))
- mark(i.io.in, "gotcha")
- mark(i.sum, "also this")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|Top/i:ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|Top/i:ModuleWithCommonIntf>sum".rt -> "also this",
- "~Top|Top/i:ModuleWithCommonIntf".it -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.2 A BlackBox that implements an @instantiable trait should be instantiable as that trait") {
- class Top extends Module {
- val i: Instance[ModuleIntf] = Module(new BlackBoxWithCommonIntf).toInstance
- mark(i.io.in, "gotcha")
- mark(i, "module")
- }
- val expected = List(
- "~Top|BlackBoxWithCommonIntf>in".rt -> "gotcha",
- "~Top|BlackBoxWithCommonIntf".mt -> "module"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.3 It should be possible to have Vectors of @instantiable traits mixing concrete subclasses") {
- class Top extends Module {
- val proto = Definition(new ModuleWithCommonIntf("X"))
- val insts: Seq[Instance[ModuleIntf]] = Vector(
- Module(new ModuleWithCommonIntf("Y")).toInstance,
- Module(new BlackBoxWithCommonIntf).toInstance,
- Instance(proto)
- )
- mark(insts(0).io.in, "foo")
- mark(insts(1).io.in, "bar")
- mark(insts(2).io.in, "fizz")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntfY>io.in".rt -> "foo",
- "~Top|BlackBoxWithCommonIntf>in".rt -> "bar",
- "~Top|Top/insts_2:ModuleWithCommonIntfX>io.in".rt -> "fizz"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
- // TODO don't forget to test this with heterogeneous Views (eg. viewing a tuple of a port and non-port as a single Bundle)
- describe("7: @instantiable and @public should compose with DataView") {
- import chisel3.experimental.dataview._
- it("7.0: should work on simple Views") {
- @instantiable
- class MyModule extends RawModule {
- val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- val sum = in + 1.U
- out := sum + 1.U
- @public val foo = in.viewAs[UInt]
- @public val bar = sum.viewAs[UInt]
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val i = Instance(Definition(new MyModule))
- i.foo := foo
- bar := i.out
- mark(i.out, "out")
- mark(i.foo, "foo")
- mark(i.bar, "bar")
- }
- val expectedAnnos = List(
- "~Top|Top/i:MyModule>out".rt -> "out",
- "~Top|Top/i:MyModule>in".rt -> "foo",
- "~Top|Top/i:MyModule>sum".rt -> "bar"
- )
- val expectedLines = List(
- "i.in <= foo",
- "bar <= i.out"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- ignore("7.1: should work on Aggregate Views") {
- import chiselTests.experimental.FlatDecoupledDataView._
- type RegDecoupled = DecoupledIO[FizzBuzz]
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Flipped(new FlatDecoupled))
- private val b = IO(new FlatDecoupled)
- @public val enq = a.viewAs[RegDecoupled]
- @public val deq = b.viewAs[RegDecoupled]
- @public val enq_valid = enq.valid // Also return a subset of the view
- deq <> enq
- }
- class Top extends RawModule {
- val foo = IO(Flipped(new RegDecoupled(new FizzBuzz)))
- val bar = IO(new RegDecoupled(new FizzBuzz))
- val i = Instance(Definition(new MyModule))
- i.enq <> foo
- i.enq_valid := foo.valid // Make sure connections also work for @public on elements of a larger Aggregate
- i.deq.ready := bar.ready
- bar.valid := i.deq.valid
- bar.bits := i.deq.bits
- mark(i.enq, "enq")
- mark(i.enq.bits, "enq.bits")
- mark(i.deq.bits.fizz, "deq.bits.fizz")
- mark(i.enq_valid, "enq_valid")
- }
- val expectedAnnos = List(
- "~Top|Top/i:MyModule>a".rt -> "enq", // Not split, checks 1:1
- "~Top|Top/i:MyModule>a.fizz".rt -> "enq.bits", // Split, checks non-1:1 inner Aggregate
- "~Top|Top/i:MyModule>a.buzz".rt -> "enq.bits",
- "~Top|Top/i:MyModule>b.fizz".rt -> "deq.bits.fizz", // Checks 1 inner Element
- "~Top|Top/i:MyModule>a.valid".rt -> "enq_valid"
- )
- val expectedLines = List(
- "i.a.valid <= foo.valid",
- "foo.ready <= i.a.ready",
- "i.a.fizz <= foo.bits.fizz",
- "i.a.buzz <= foo.bits.buzz",
- "bar.valid <= i.b.valid",
- "i.b.ready <= bar.ready",
- "bar.bits.fizz <= i.b.fizz",
- "bar.bits.buzz <= i.b.buzz"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- it("7.2: should work on views of views") {
- import chiselTests.experimental.SimpleBundleDataView._
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Input(UInt(8.W)))
- private val b = IO(Output(new BundleA(8)))
- @public val in = a.viewAs[UInt].viewAs[UInt]
- @public val out = b.viewAs[BundleB].viewAs[BundleA].viewAs[BundleB]
- out.bar := in
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(new BundleB(8)))
- val i = Instance(Definition(new MyModule))
- i.in := foo
- bar := i.out
- bar.bar := i.out.bar
- mark(i.in, "in")
- mark(i.out.bar, "out_bar")
- }
- val expected = List(
- "~Top|Top/i:MyModule>a".rt -> "in",
- "~Top|Top/i:MyModule>b.foo".rt -> "out_bar"
- )
- val lines = List(
- "i.a <= foo",
- "bar.bar <= i.b.foo"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- lines) {
- text should include(line)
- }
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- it("7.3: should work with DataView + implicit conversion") {
- import chisel3.experimental.conversions._
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Input(UInt(8.W)))
- private val b = IO(Output(UInt(8.W)))
- @public val ports = Seq(a, b)
- b := a
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val i = Instance(Definition(new MyModule))
- i.ports <> Seq(foo, bar)
- mark(i.ports, "i.ports")
- }
- val expected = List(
- // Not 1:1 so will get split out
- "~Top|Top/i:MyModule>a".rt -> "i.ports",
- "~Top|Top/i:MyModule>b".rt -> "i.ports"
- )
- val lines = List(
- "i.a <= foo",
- "bar <= i.b"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- lines) {
- text should include(line)
- }
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- it("7.4: should work on Views of BlackBoxes") {
- @instantiable
- class MyBlackBox extends BlackBox {
- @public val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- @public val innerView = io.viewAs
- @public val foo = io.in.viewAs[UInt]
- @public val bar = io.out.viewAs[UInt]
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val i = Instance(Definition(new MyBlackBox))
- val outerView = i.io.viewAs
- i.foo := foo
- bar := i.bar
- mark(i.foo, "i.foo")
- mark(i.bar, "i.bar")
- mark(i.innerView.in, "i.innerView.in")
- mark(outerView.out, "outerView.out")
- }
- val inst = "~Top|Top/i:MyBlackBox"
- val expectedAnnos = List(
- s"$inst>in".rt -> "i.foo",
- s"$inst>out".rt -> "i.bar",
- s"$inst>in".rt -> "i.innerView.in",
- s"$inst>out".rt -> "outerView.out"
- )
- val expectedLines = List(
- "i.in <= foo",
- "bar <= i.out"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- }
-
- describe("8: @instantiable and @public should compose with CloneModuleAsRecord") {
- it("8.0: it should support @public on a CMAR Record in Definitions") {
- @instantiable
- class HasCMAR extends Module {
- @public val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- @public val m = Module(new AggregatePortModule)
- @public val c = experimental.CloneModuleAsRecord(m)
- }
- class Top extends Module {
- val d = Definition(new HasCMAR)
- mark(d.c("io"), "c.io")
- val bun = d.c("io").asInstanceOf[Record]
- mark(bun.elements("out"), "c.io.out")
- }
- val expected = List(
- "~Top|HasCMAR/c:AggregatePortModule>io".rt -> "c.io",
- "~Top|HasCMAR/c:AggregatePortModule>io.out".rt -> "c.io.out"
- )
- val (_, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("8.1: it should support @public on a CMAR Record in Instances") {
- @instantiable
- class HasCMAR extends Module {
- @public val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- @public val m = Module(new AggregatePortModule)
- @public val c = experimental.CloneModuleAsRecord(m)
- }
- class Top extends Module {
- val i = Instance(Definition(new HasCMAR))
- mark(i.c("io"), "i.c.io")
- val bun = i.c("io").asInstanceOf[Record]
- mark(bun.elements("out"), "i.c.io.out")
- }
- val expected = List(
- "~Top|Top/i:HasCMAR/c:AggregatePortModule>io".rt -> "i.c.io",
- "~Top|Top/i:HasCMAR/c:AggregatePortModule>io.out".rt -> "i.c.io.out"
- )
- val (_, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
- describe("9: isA[..]") {
- it("9.0: it should work on simple classes") {
- class Top extends Module {
- val d = Definition(new AddOne)
- require(d.isA[AddOne])
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.1: it should not work on inner classes") {
- class InnerClass extends Module
- class Top extends Module {
- val d = Definition(new InnerClass)
- "require(d.isA[Module])" should compile // ensures that the test below is checking something useful
- "require(d.isA[InnerClass])" shouldNot compile
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.2: it should work on super classes") {
- class InnerClass extends Module
- class Top extends Module {
- val d = Definition(new InnerClass)
- require(d.isA[Module])
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.2: it should work after casts") {
- class Top extends Module {
- val d0: Definition[Module] = Definition(new AddOne)
- require(d0.isA[AddOne])
- val d1: Definition[Module] = Definition((new AddOne).asInstanceOf[Module])
- require(d1.isA[AddOne])
- val i0: Instance[Module] = Instance(d0)
- require(i0.isA[AddOne])
- val i1: Instance[Module] = Instance(d1)
- require(i1.isA[AddOne])
- val i2: Instance[Module] = Instance(Definition(new AddOne))
- require(i2.isA[AddOne])
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.3 it should ignore type parameters (even though it would be nice if it didn't)") {
- class Top extends Module {
- val d0: Definition[Module] = Definition(new HasTypeParams(Bool()))
- require(d0.isA[HasTypeParams[Bool]])
- require(d0.isA[HasTypeParams[_]])
- require(d0.isA[HasTypeParams[UInt]])
- require(!d0.isA[HasBlah])
- }
- getFirrtlAndAnnos(new Top)
- }
- }
- describe("10: Select APIs") {
- it("10.0: instancesOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val targets = aop.Select.instancesOf[AddOne](m.toDefinition).map { i: Instance[AddOne] => i.toTarget }
- targets should be(
- Seq(
- "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it,
- "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.1: instancesIn") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val insts = aop.Select.instancesIn(m.toDefinition)
- val abs = insts.map { i: Instance[BaseModule] => i.toAbsoluteTarget }
- val rel = insts.map { i: Instance[BaseModule] => i.toTarget }
- abs should be(
- Seq(
- "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it,
- "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it
- )
- )
- rel should be(
- Seq(
- "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it,
- "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.2: allInstancesOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val insts = aop.Select.allInstancesOf[AddOne](m.toDefinition)
- val abs = insts.map { i: Instance[AddOne] => i.in.toAbsoluteTarget }
- val rel = insts.map { i: Instance[AddOne] => i.in.toTarget }
- rel should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt
- )
- )
- abs should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.3: definitionsOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val targets = aop.Select.definitionsOf[AddOne](m.toDefinition).map { i: Definition[AddOne] => i.in.toTarget }
- targets should be(
- Seq(
- "~AddTwoMixedModules|AddOne>in".rt,
- "~AddTwoMixedModules|AddOne_1>in".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.4: definitionsIn") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val targets = aop.Select.definitionsIn(m.toDefinition).map { i: Definition[BaseModule] => i.toTarget }
- targets should be(
- Seq(
- "~AddTwoMixedModules|AddOne".mt,
- "~AddTwoMixedModules|AddOne_1".mt
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.5: allDefinitionsOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val targets = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).map { i: Definition[AddOne] => i.in.toTarget }
- targets should be(
- Seq(
- "~AddFour|AddOne>in".rt,
- "~AddFour|AddOne_1>in".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.6: Select.collectDeep should fail when combined with hierarchy package") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- aop.Select.collectDeep(m) { case m: AddOne => m.toTarget }
- })
- intercept[Exception] { getFirrtlAndAnnos(new AddFour, Seq(aspect)) }
- }
- it("10.7: Select.getDeep should fail when combined with hierarchy package") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- aop.Select.getDeep(m) { m: BaseModule => Nil }
- })
- intercept[Exception] { getFirrtlAndAnnos(new AddFour, Seq(aspect)) }
- }
- it("10.8: Select.instances should fail when combined with hierarchy package") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- aop.Select.instances(m)
- })
- intercept[Exception] { getFirrtlAndAnnos(new AddFour, Seq(aspect)) }
- }
- it("10.9: allInstancesOf.ios") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val abs = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] =>
- aop.Select.ios(i).map(_.toAbsoluteTarget)
- }
- val rel = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] =>
- aop.Select.ios(i).map(_.toTarget)
- }
- abs should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt
- )
- )
-
- rel should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.10: allDefinitionsOf.ios") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val abs = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] =>
- aop.Select.ios(i).map(_.toAbsoluteTarget)
- }
- val rel = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] =>
- aop.Select.ios(i).map(_.toTarget)
- }
- abs should be(
- Seq(
- "~AddFour|AddOne>clock".rt,
- "~AddFour|AddOne>reset".rt,
- "~AddFour|AddOne>in".rt,
- "~AddFour|AddOne>out".rt,
- "~AddFour|AddOne_1>clock".rt,
- "~AddFour|AddOne_1>reset".rt,
- "~AddFour|AddOne_1>in".rt,
- "~AddFour|AddOne_1>out".rt
- )
- )
-
- rel should be(
- Seq(
- "~AddFour|AddOne>clock".rt,
- "~AddFour|AddOne>reset".rt,
- "~AddFour|AddOne>in".rt,
- "~AddFour|AddOne>out".rt,
- "~AddFour|AddOne_1>clock".rt,
- "~AddFour|AddOne_1>reset".rt,
- "~AddFour|AddOne_1>in".rt,
- "~AddFour|AddOne_1>out".rt
- )
- )
-
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.11 Select.instancesIn for typed BaseModules") {
- val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside =>
- val targets = aop.Select.instancesIn(m.toDefinition).map { i: Instance[BaseModule] => i.toTarget }
- targets should be(
- Seq(
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it
- )
- )
- })
- getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect))
- }
- it("10.12 Select.instancesOf for typed BaseModules if type is ignored") {
- val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside =>
- val targets =
- aop.Select.instancesOf[HasTypeParams[_]](m.toDefinition).map { i: Instance[HasTypeParams[_]] => i.toTarget }
- targets should be(
- Seq(
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it
- )
- )
- })
- getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect))
- }
- it(
- "10.13 Select.instancesOf for typed BaseModules even type is specified wrongly (should be ignored, even though we wish it weren't)"
- ) {
- val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside =>
- val targets = aop.Select.instancesOf[HasTypeParams[SInt]](m.toDefinition).map { i: Instance[HasTypeParams[_]] =>
- i.toTarget
- }
- targets should be(
- Seq(
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it
- )
- )
- })
- getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect))
- }
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala
deleted file mode 100644
index 25bbc474..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala
+++ /dev/null
@@ -1,495 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import chiselTests.ChiselFunSpec
-import chisel3._
-import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselStage, DesignAnnotation}
-import chisel3.experimental.hierarchy.{Definition, Instance}
-import chisel3.experimental.hierarchy.ImportDefinitionAnnotation
-import firrtl.AnnotationSeq
-import firrtl.options.TargetDirAnnotation
-
-import scala.io.Source
-
-class SeparateElaborationSpec extends ChiselFunSpec with Utils {
- import Examples._
-
- /** Return a [[DesignAnnotation]] from a list of annotations. */
- private def getDesignAnnotation[T <: RawModule](annos: AnnotationSeq): DesignAnnotation[T] = {
- val designAnnos = annos.flatMap { a =>
- a match {
- case a: DesignAnnotation[T] => Some(a)
- case _ => None
- }
- }
- require(designAnnos.length == 1, s"Exactly one DesignAnnotation should exist, but found: $designAnnos.")
- designAnnos.head
- }
-
- /** Elaborates [[AddOne]] and returns its [[Definition]]. */
- private def getAddOneDefinition(testDir: String): Definition[AddOne] = {
- val dutAnnos = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOne),
- TargetDirAnnotation(testDir)
- )
- )
-
- // Grab DUT definition to pass into testbench
- getDesignAnnotation(dutAnnos).design.asInstanceOf[AddOne].toDefinition
- }
-
- /** Return [[Definition]]s of all modules in a circuit. */
- private def allModulesToImportedDefs(annos: AnnotationSeq): Seq[ImportDefinitionAnnotation[_]] = {
- annos.flatMap { a =>
- a match {
- case a: ChiselCircuitAnnotation =>
- a.circuit.components.map { c => ImportDefinitionAnnotation(c.id.toDefinition) }
- case _ => Seq.empty
- }
- }
- }
-
- describe("(0): Name conflicts") {
- it("(0.a): should not occur between a Module and an Instance of a previously elaborated Definition.") {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val mod = Module(new AddOne)
- val inst = Instance(defn)
-
- // Tie inputs to a value so ChiselStage does not complain
- mod.in := 0.U
- inst.in := 0.U
- dontTouch(mod.out)
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef)
- )
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("module AddOne_1(")
- tb_rtl should include("AddOne_1 mod (")
- (tb_rtl should not).include("module AddOne(")
- tb_rtl should include("AddOne inst (")
- }
-
- it(
- "(0.b): should not occur between an Instance of a Definition and an Instance of a previously elaborated Definition."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val inst0 = Instance(Definition(new AddOne))
- val inst1 = Instance(defn)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- dontTouch(inst0.out)
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef)
- )
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("module AddOne_1(")
- tb_rtl should include("AddOne_1 inst0 (")
- (tb_rtl should not).include("module AddOne(")
- tb_rtl should include("AddOne inst1 (")
- }
- }
-
- describe("(1): Repeat Module definitions") {
- it("(1.a): should not occur when elaborating multiple Instances separately from its Definition.") {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val inst0 = Instance(defn)
- val inst1 = Instance(defn)
-
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- // If there is a repeat module definition, FIRRTL emission will fail
- (new ChiselStage).emitFirrtl(
- gen = new Testbench(dutDef),
- args = Array("-td", testDir, "--full-stacktrace"),
- annotations = Seq(ImportDefinitionAnnotation(dutDef))
- )
- }
- }
-
- describe("(2): Multiple imported Definitions of modules without submodules") {
- it(
- "(2.a): should work if a list of imported Definitions is passed between Stages."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1"),
- // pass in previously elaborated Definitions
- ImportDefinitionAnnotation(dutDef0)
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0),
- ImportDefinitionAnnotation(dutDef1)
- )
- )
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized_1(")
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("AddOneParameterized inst0 (")
- tb_rtl should include("AddOneParameterized_1 inst1 (")
- (tb_rtl should not).include("module AddOneParameterized(")
- (tb_rtl should not).include("module AddOneParameterized_1(")
- }
-
- it(
- "(2.b): should throw an exception if information is not passed between Stages."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1")
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- // Because these elaborations have no knowledge of each other, they create
- // modules of the same name
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized(")
-
- val errMsg = intercept[ChiselException] {
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0),
- ImportDefinitionAnnotation(dutDef1)
- )
- )
- }
- errMsg.getMessage should include(
- "Expected distinct imported Definition names but found duplicates for: AddOneParameterized"
- )
- }
- }
-
- describe("(3): Multiple imported Definitions of modules with submodules") {
- it(
- "(3.a): should work if a list of imported Definitions for all modules is passed between Stages."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos0 = allModulesToImportedDefs(dutAnnos0)
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- TargetDirAnnotation(s"$testDir/dutDef1")
- ) ++ importDefinitionAnnos0
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos1 = allModulesToImportedDefs(dutAnnos1)
-
- class Testbench(defn0: Definition[AddTwoMixedModules], defn1: Definition[AddTwoMixedModules]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddTwoMixedModules.v").getLines.mkString
- dutDef0_rtl should include("module AddOne(")
- dutDef0_rtl should include("module AddTwoMixedModules(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddTwoMixedModules_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOne_2(")
- dutDef1_rtl should include("module AddTwoMixedModules_1(")
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir)
- ) ++ importDefinitionAnnos0 ++ importDefinitionAnnos1
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("AddTwoMixedModules inst0 (")
- tb_rtl should include("AddTwoMixedModules_1 inst1 (")
- (tb_rtl should not).include("module AddTwoMixedModules(")
- (tb_rtl should not).include("module AddTwoMixedModules_1(")
- }
- }
-
- it(
- "(3.b): should throw an exception if submodules are not passed between Definition elaborations."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos0 = allModulesToImportedDefs(dutAnnos0)
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- ImportDefinitionAnnotation(dutDef0),
- TargetDirAnnotation(s"$testDir/dutDef1")
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos1 = allModulesToImportedDefs(dutAnnos1)
-
- class Testbench(defn0: Definition[AddTwoMixedModules], defn1: Definition[AddTwoMixedModules]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddTwoMixedModules.v").getLines.mkString
- dutDef0_rtl should include("module AddOne(")
- dutDef0_rtl should include("module AddTwoMixedModules(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddTwoMixedModules_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOne(")
- dutDef1_rtl should include("module AddTwoMixedModules_1(")
-
- val errMsg = intercept[ChiselException] {
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir)
- ) ++ importDefinitionAnnos0 ++ importDefinitionAnnos1
- )
- }
- errMsg.getMessage should include(
- "Expected distinct imported Definition names but found duplicates for: AddOne"
- )
- }
-
- describe("(4): With ExtMod Names") {
- it("(4.a): should pick correct ExtMod names when passed") {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val mod = Module(new AddOne)
- val inst = Instance(defn)
-
- // Tie inputs to a value so ChiselStage does not complain
- mod.in := 0.U
- inst.in := 0.U
- dontTouch(mod.out)
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef, Some("CustomPrefix_AddOne_CustomSuffix"))
- )
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
-
- tb_rtl should include("module AddOne_1(")
- tb_rtl should include("AddOne_1 mod (")
- (tb_rtl should not).include("module AddOne(")
- tb_rtl should include("CustomPrefix_AddOne_CustomSuffix inst (")
- }
- }
-
- it(
- "(4.b): should work if a list of imported Definitions is passed between Stages with ExtModName."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1"),
- // pass in previously elaborated Definitions
- ImportDefinitionAnnotation(dutDef0)
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0, Some("Inst1_Prefix_AddOnePramaterized_Inst1_Suffix")),
- ImportDefinitionAnnotation(dutDef1, Some("Inst2_Prefix_AddOnePrameterized_1_Inst2_Suffix"))
- )
- )
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized_1(")
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("Inst1_Prefix_AddOnePramaterized_Inst1_Suffix inst0 (")
- tb_rtl should include("Inst2_Prefix_AddOnePrameterized_1_Inst2_Suffix inst1 (")
- (tb_rtl should not).include("module AddOneParameterized(")
- (tb_rtl should not).include("module AddOneParameterized_1(")
- }
-
- it(
- "(4.c): should throw an exception if a list of imported Definitions is passed between Stages with same ExtModName."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val importDefinitionAnnos0 = allModulesToImportedDefs(dutAnnos0)
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1"),
- // pass in previously elaborated Definitions
- ImportDefinitionAnnotation(dutDef0)
- )
- )
- val importDefinitionAnnos1 = allModulesToImportedDefs(dutAnnos1)
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized_1(")
-
- val errMsg = intercept[ChiselException] {
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0, Some("Inst1_Prefix_AddOnePrameterized_Inst1_Suffix")),
- ImportDefinitionAnnotation(dutDef1, Some("Inst1_Prefix_AddOnePrameterized_Inst1_Suffix"))
- )
- )
- }
- errMsg.getMessage should include(
- "Expected distinct overrideDef names but found duplicates for: Inst1_Prefix_AddOnePrameterized_Inst1_Suffix"
- )
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala b/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala
deleted file mode 100644
index a2e51765..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import chisel3._
-import _root_.firrtl.annotations._
-import chisel3.stage.{ChiselCircuitAnnotation, CircuitSerializationAnnotation, DesignAnnotation}
-import chiselTests.ChiselRunners
-import firrtl.stage.FirrtlCircuitAnnotation
-import org.scalatest.matchers.should.Matchers
-
-trait Utils extends ChiselRunners with chiselTests.Utils with Matchers {
- import Annotations._
- // TODO promote to standard API (in FIRRTL) and perhaps even implement with a macro
- implicit class Str2RefTarget(str: String) {
- def rt: ReferenceTarget = Target.deserialize(str).asInstanceOf[ReferenceTarget]
- def it: InstanceTarget = Target.deserialize(str).asInstanceOf[InstanceTarget]
- def mt: ModuleTarget = Target.deserialize(str).asInstanceOf[ModuleTarget]
- def ct: CircuitTarget = Target.deserialize(str).asInstanceOf[CircuitTarget]
- }
-}