diff options
| author | Jack | 2016-11-11 14:37:03 -0800 |
|---|---|---|
| committer | Jack Koenig | 2016-11-14 11:11:02 -0800 |
| commit | 815b1c3cb311b7f4dfb7a2f00e0e2d62795bdc6b (patch) | |
| tree | c9cb68e6cbb844a0da9af23afce1b470a2d3481e /chiselFrontend | |
| parent | e60761cf72ba572da0bb8387a4506f5c3e211ac9 (diff) | |
Add checks for misuse or omission of Module()
Implemented by adding a Boolean to check for alternating invocations of object
Module.apply and the constructor of abstract class Module.
Fixes #192
Diffstat (limited to 'chiselFrontend')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Module.scala | 18 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 7 |
2 files changed, 24 insertions, 1 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index c3353d85..ca391091 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -25,9 +25,21 @@ object Module { // module de-duplication in FIRRTL emission. val childSourceInfo = UnlocatableSourceInfo + if (Builder.readyForModuleConstr) { + throwException("Error: Called Module() twice without instantiating a Module." + + sourceInfo.makeMessage(" See " + _)) + } + Builder.readyForModuleConstr = true val parent: Option[Module] = Builder.currentModule - val m = bc.setRefs() // This will set currentModule! + + val m = bc.setRefs() // This will set currentModule and unset readyForModuleConstr!!! m._commands.prepend(DefInvalid(childSourceInfo, m.io.ref)) // init module outputs + + if (Builder.readyForModuleConstr) { + throwException("Error: attempted to instantiate a Module, but nothing happened. " + + "This is probably due to rewrapping a Module instance with Module()." + + sourceInfo.makeMessage(" See " + _)) + } Builder.currentModule = parent // Back to parent! val ports = m.computePorts val component = Component(m, m.name, ports, m._commands) @@ -93,6 +105,10 @@ extends HasId { private[chisel3] val _commands = ArrayBuffer[Command]() private[core] val _ids = ArrayBuffer[HasId]() Builder.currentModule = Some(this) + if (!Builder.readyForModuleConstr) { + throwException("Error: attempted to instantiate a Module without wrapping it in Module().") + } + readyForModuleConstr = false /** Desired name of this module. */ def desiredName = this.getClass.getName.split('.').last diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index b4b0e028..028ce628 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -146,6 +146,9 @@ private[chisel3] class DynamicContext() { val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() var currentModule: Option[Module] = None + // Set by object Module.apply before calling class Module constructor + // Used to distinguish between no Module() wrapping, multiple wrappings, and rewrapping + var readyForModuleConstr: Boolean = false val errors = new ErrorLog } @@ -170,6 +173,10 @@ private[chisel3] object Builder { // A bare api call is, e.g. calling Wire() from the scala console). ) } + def readyForModuleConstr: Boolean = dynamicContext.readyForModuleConstr + def readyForModuleConstr_=(target: Boolean): Unit = { + dynamicContext.readyForModuleConstr = target + } // TODO(twigg): Ideally, binding checks and new bindings would all occur here // However, rest of frontend can't support this yet. |
