diff options
| author | Megan Wachs | 2022-01-07 15:28:56 -0800 |
|---|---|---|
| committer | GitHub | 2022-01-07 23:28:56 +0000 |
| commit | a1af6b7099f1207c67db3561507615fd18c487ef (patch) | |
| tree | 86083634d8b7a67ff0a249768692164737f35de3 /src | |
| parent | 72d5be9634c677e47ec8fce204be55c8936166fb (diff) | |
Add a Select.ios that works with Definition/Instance, fix isA behavior (#2315)
* New Feature: Add a Select.ios that works with Definition/Instance
* BugFix: isA now truly ignores type parameters
Diffstat (limited to 'src')
4 files changed, 155 insertions, 3 deletions
diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala index 8f5a2577..6bd13445 100644 --- a/src/main/scala/chisel3/aop/Select.scala +++ b/src/main/scala/chisel3/aop/Select.scala @@ -65,6 +65,8 @@ object Select { /** Selects all Instances of instances/modules directly instantiated within given module, of provided type * * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class. + * @note IMPORTANT: this function ignores type parameters. E.g. instancesOf[List[Int]] would return List[String]. + * * @param parent hierarchy which instantiates the returned Definitions */ def instancesOf[T <: BaseModule : TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = { @@ -90,6 +92,8 @@ object Select { /** Selects all Instances directly and indirectly instantiated within given root hierarchy, of provided type * * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class. + * @note IMPORTANT: this function ignores type parameters. E.g. allInstancesOf[List[Int]] would return List[String]. + * * @param root top of the hierarchy to search for instances/modules of given type */ def allInstancesOf[T <: BaseModule : TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = { @@ -128,6 +132,8 @@ object Select { /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type * * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class. + * @note IMPORTANT: this function ignores type parameters. E.g. definitionsOf[List[Int]] would return List[String]. + * * @param parent hierarchy which instantiates the returned Definitions */ def definitionsOf[T <: BaseModule : TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = { @@ -158,6 +164,8 @@ object Select { * * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class, i.e. * a class defined within another class. + * @note IMPORTANT: this function ignores type parameters. E.g. allDefinitionsOf[List[Int]] would return List[String]. + * * @param root top of the hierarchy to search for definitions of given type */ def allDefinitionsOf[T <: BaseModule : TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = { @@ -253,7 +261,7 @@ object Select { } } - /** Selects all ios directly contained within given module + /** Selects all ios on a given module * @param module */ def ios(module: BaseModule): Seq[Data] = { @@ -261,6 +269,15 @@ object Select { module._component.get.asInstanceOf[DefModule].ports.map(_.id) } + /** Selects all ios directly on a given Instance or Definition of a module + * @param parent the Definition or Instance to get the IOs of + */ + def ios[T <: BaseModule](parent: Hierarchy[T]): Seq[Data] = { + check(parent) + implicit val mg = new chisel3.internal.MacroGenerated{} + parent._lookup { x => ios(parent.proto) } + } + /** Selects all SyncReadMems directly contained within given module * @param module */ diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala index dc7e6487..ed59d4fb 100644 --- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala +++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala @@ -4,7 +4,6 @@ package chisel3.aop.injecting import chisel3.{Module, ModuleAspect, RawModule, withClockAndReset} import chisel3.aop._ -import chisel3.experimental.hierarchy.IsInstantiable import chisel3.internal.{Builder, DynamicContext} import chisel3.internal.firrtl.DefModule import chisel3.stage.DesignAnnotation diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala index c0f504ff..996b36ee 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala @@ -236,4 +236,14 @@ object Examples { 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) + } } diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala index 9ceb9b40..94af9a8b 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala @@ -754,6 +754,16 @@ class InstanceSpec extends ChiselFunSpec with Utils { } 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") { @@ -850,6 +860,122 @@ class InstanceSpec extends ChiselFunSpec with Utils { }) 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)) + } } } - |
