From 2416d1d44a2bd73bd0556437ece7a7a24d649a7a Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Thu, 25 Oct 2018 13:37:00 -0400 Subject: Make BaseModule.name lazy This changes BaseModule.name to be lazy (instead of eager) to enable a desiredName to be a function of a sub-instance. This includes a test case showing the new behavior. Signed-off-by: Schuyler Eldridge --- chiselFrontend/src/main/scala/chisel3/core/Module.scala | 2 +- src/test/scala/chiselTests/Module.scala | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 88013bae..89dd2dee 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -180,7 +180,7 @@ abstract class BaseModule extends HasId { def desiredName = this.getClass.getName.split('.').last /** Legalized name of this module. */ - final val name = Builder.globalNamespace.name(desiredName) + final lazy val name = Builder.globalNamespace.name(desiredName) /** Returns a FIRRTL ModuleName that references this object * @note Should not be called until circuit elaboration is complete diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index 968e7578..dc44838a 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -62,6 +62,12 @@ class ModuleRewrap extends Module { val inst2 = Module(inst) } +class ModuleWrapper(gen: => Module) extends Module { + val io = IO(new Bundle{}) + val child = Module(gen) + override lazy val desiredName = s"${child.desiredName}Wrapper" +} + class ModuleSpec extends ChiselPropSpec { property("ModuleVec should elaborate") { @@ -138,4 +144,7 @@ class ModuleSpec extends ChiselPropSpec { "a" -> m.a, "b" -> m.b)) }) } + property("A desiredName parameterized by a submodule should work") { + Driver.elaborate(() => new ModuleWrapper(new ModuleWire)).name should be ("ModuleWireWrapper") + } } -- cgit v1.2.3 From f64388e7cfe71004df93ddeef88447978f37ecb1 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Thu, 25 Oct 2018 16:27:49 -0400 Subject: Check BaseModule.name for NullPointerException This wraps the evaluation of BaseModule.name in try/catch to look for a NullPointerException that may result from trying to evaluate desiredName before it's ready. This catches a test case of using a desiredName that depends on a later defined eager subinstance. h/t @jackkoenig Signed-off-by: Schuyler Eldridge --- chiselFrontend/src/main/scala/chisel3/core/Module.scala | 8 +++++++- src/test/scala/chiselTests/Module.scala | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index 89dd2dee..3bdc86d6 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -180,7 +180,13 @@ abstract class BaseModule extends HasId { def desiredName = this.getClass.getName.split('.').last /** Legalized name of this module. */ - final lazy val name = Builder.globalNamespace.name(desiredName) + final lazy val name = try { + Builder.globalNamespace.name(desiredName) + } catch { + case e: NullPointerException => throwException( + s"Error: desiredName of ${this.getClass.getName} is null. Did you evaluate 'name' before all values needed by desiredName were available?", e) + case t: Throwable => throw t + } /** Returns a FIRRTL ModuleName that references this object * @note Should not be called until circuit elaboration is complete diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index dc44838a..b3d1899c 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -65,7 +65,14 @@ class ModuleRewrap extends Module { class ModuleWrapper(gen: => Module) extends Module { val io = IO(new Bundle{}) val child = Module(gen) + override val desiredName = s"${child.desiredName}Wrapper" +} + +class NullModuleWrapper extends Module { + val io = IO(new Bundle{}) override lazy val desiredName = s"${child.desiredName}Wrapper" + println(s"My name is ${name}") + val child = Module(new ModuleWire) } class ModuleSpec extends ChiselPropSpec { @@ -147,4 +154,8 @@ class ModuleSpec extends ChiselPropSpec { property("A desiredName parameterized by a submodule should work") { Driver.elaborate(() => new ModuleWrapper(new ModuleWire)).name should be ("ModuleWireWrapper") } + property("A name generating a null pointer exception should provide a good error message") { + (the [Exception] thrownBy (Driver.elaborate(() => new NullModuleWrapper))) + .getMessage should include ("desiredName of chiselTests.NullModuleWrapper is null") + } } -- cgit v1.2.3