diff options
| author | Jack | 2021-12-18 08:27:38 +0000 |
|---|---|---|
| committer | Jack | 2021-12-18 08:27:38 +0000 |
| commit | dd9ad534771247ac16eaa47eb9794102736b5102 (patch) | |
| tree | d4566d317cb8526b79017de1e438aea8217dd1d4 /src/test/scala/chiselTests/experimental/hierarchy | |
| parent | 440edc4436fb3a8a4175ae425a0d31c4997ee60f (diff) | |
| parent | f50f74f583fba7b98e550c440df091e559ce32b8 (diff) | |
Merge branch 'master' into 3.5-release
Diffstat (limited to 'src/test/scala/chiselTests/experimental/hierarchy')
4 files changed, 260 insertions, 16 deletions
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala index 43111fdd..eba412f1 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala @@ -5,24 +5,20 @@ package chiselTests.experimental.hierarchy import _root_.firrtl.annotations._ import chisel3.experimental.{annotate, BaseModule} import chisel3.Data -import chisel3.experimental.hierarchy.{Instance, Definition} +import chisel3.experimental.hierarchy.{Instance, Definition, Hierarchy} object Annotations { case class MarkAnnotation(target: IsMember, tag: String) extends SingleTargetAnnotation[IsMember] { def duplicate(n: IsMember): Annotation = this.copy(target = n) } - case class MarkChiselInstanceAnnotation[B <: BaseModule](d: Instance[B], tag: String, isAbsolute: Boolean) extends chisel3.experimental.ChiselAnnotation { - def toFirrtl = MarkAnnotation(d.toTarget, tag) - } - case class MarkChiselDefinitionAnnotation[B <: BaseModule](d: Definition[B], tag: String, isAbsolute: Boolean) extends chisel3.experimental.ChiselAnnotation { + 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) } def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false)) - def mark[B <: BaseModule](d: Instance[B], tag: String): Unit = annotate(MarkChiselInstanceAnnotation(d, tag, false)) - def mark[B <: BaseModule](d: Definition[B], tag: String): Unit = annotate(MarkChiselDefinitionAnnotation(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: Instance[B], tag: String): Unit = annotate(MarkChiselInstanceAnnotation(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 index 19261c36..f33f7869 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala @@ -40,6 +40,44 @@ class DefinitionSpec extends ChiselFunSpec with Utils { 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") { @@ -97,7 +135,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { mark(definition.i1, "i0.i1") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_2".it, "i0.i1")) + 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 @@ -258,6 +296,17 @@ class DefinitionSpec extends ChiselFunSpec with Utils { 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")) + } } describe("4: toDefinition") { it("4.0: should work on modules") { @@ -311,7 +360,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { amark(i.i1.in, "blah") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_2>in".rt, "blah")) + 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 { @@ -319,7 +368,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { amark(i.i1.x.head, "blah") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain(MarkAnnotation("~Top|InstantiatesHasVec/i1:HasVec_2>x[0]".rt, "blah")) + annos should contain(MarkAnnotation("~Top|InstantiatesHasVec/i1:HasVec_1>x[0]".rt, "blah")) } } describe("6: @instantiable traits should work as expected") { diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala index 23b8c9c0..c0f504ff 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala @@ -36,6 +36,19 @@ object Examples { 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 AddTwo extends Module { @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @@ -58,6 +71,33 @@ object Examples { 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)) @@ -183,4 +223,17 @@ object Examples { @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) + } } diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala index 3866bf87..9ceb9b40 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala @@ -89,7 +89,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(i0.i1, "i0.i1") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddTwoMixedModules/i1:AddOne_2".it, "i0.i1")) + 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 { @@ -144,6 +144,15 @@ class InstanceSpec extends ChiselFunSpec with Utils { 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") { @@ -353,7 +362,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { amark(i.i1.in, "blah") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain(MarkAnnotation("~Top|Top/i:AddTwoMixedModules/i1:AddOne_2>in".rt, "blah")) + 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 { @@ -361,7 +370,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { amark(i.i1.x.head, "blah") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_2>x[0]".rt, "blah")) + 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) } @@ -379,7 +388,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { amark(i.i1.x.head.x, "blah") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_2>x[0].x".rt, "blah")) + 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 { @@ -620,7 +629,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { } it("7.3: should work with DataView + implicit conversion") { - import chiselTests.experimental.SeqToVec._ + import chisel3.experimental.conversions._ @instantiable class MyModule extends RawModule { private val a = IO(Input(UInt(8.W))) @@ -705,5 +714,142 @@ class InstanceSpec extends ChiselFunSpec with Utils { } } } + 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) + } + } + 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)) } + } + } } |
