diff options
| author | Aditya Naik | 2023-11-23 03:11:56 -0800 |
|---|---|---|
| committer | Aditya Naik | 2023-11-23 03:11:56 -0800 |
| commit | af415532cf160e63e971ceb301833b8433c18a50 (patch) | |
| tree | 1fef70139846f57298c8e24a590490a74249f7dd /src/test/scala/chiselTests/experimental | |
| parent | 8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff) | |
cleanup
Diffstat (limited to 'src/test/scala/chiselTests/experimental')
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] - } -} |
