summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/Module.scala
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Module.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Module.scala57
1 files changed, 31 insertions, 26 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
index fa9ab082..74479c6b 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
@@ -191,7 +191,7 @@ abstract class BaseModule extends HasId {
*
* TODO: remove this, perhaps by removing Bindings checks in compatibility mode.
*/
- def _autoWrapPorts() {}
+ def _compatAutoWrapPorts() {}
//
// BaseModule User API functions
@@ -200,29 +200,10 @@ abstract class BaseModule extends HasId {
Builder.annotations += annotation
}
- /**
- * This must wrap the datatype used to set the io field of any Module.
- * i.e. All concrete modules must have defined io in this form:
- * [lazy] val io[: io type] = IO(...[: io type])
- *
- * Items in [] are optional.
- *
- * The granted iodef WILL NOT be cloned (to allow for more seamless use of
- * anonymous Bundles in the IO) and thus CANNOT have been bound to any logic.
- * This will error if any node is bound (e.g. due to logic in a Bundle
- * constructor, which is considered improper).
- *
- * Also registers a Data as a port, also performing bindings. Cannot be called once ports are
- * requested (so that all calls to ports will return the same information).
- * Internal API.
- *
- * TODO(twigg): Specifically walk the Data definition to call out which nodes
- * are problematic.
- */
- protected def IO[T<:Data](iodef: T): iodef.type = {
- require(!_closed, "Can't add more ports after module close")
- requireIsChiselType(iodef, "io type")
-
+ /** Chisel2 code didn't require the IO(...) wrapper and would assign a Chisel type directly to
+ * io, then do operations on it. This binds a Chisel type in-place (mutably) as an IO.
+ */
+ protected def _bindIoInPlace(iodef: Data): Unit = {
// Compatibility code: Chisel2 did not require explicit direction on nodes
// (unspecified treated as output, and flip on nothing was input).
// This sets assigns the explicit directions required by newer semantics on
@@ -249,10 +230,34 @@ abstract class BaseModule extends HasId {
}
assignCompatDir(iodef, false)
- // Bind each element of the iodef to being a Port
iodef.bind(PortBinding(this))
_ports += iodef
- iodef
+ }
+
+ /**
+ * This must wrap the datatype used to set the io field of any Module.
+ * i.e. All concrete modules must have defined io in this form:
+ * [lazy] val io[: io type] = IO(...[: io type])
+ *
+ * Items in [] are optional.
+ *
+ * The granted iodef must be a chisel type and not be bound to hardware.
+ *
+ * Also registers a Data as a port, also performing bindings. Cannot be called once ports are
+ * requested (so that all calls to ports will return the same information).
+ * Internal API.
+ *
+ * TODO(twigg): Specifically walk the Data definition to call out which nodes
+ * are problematic.
+ */
+ protected def IO[T<:Data](iodef: T): T = {
+ require(!_closed, "Can't add more ports after module close")
+ requireIsChiselType(iodef, "io type")
+
+ // Clone the IO so we preserve immutability of data types
+ val iodefClone = iodef.cloneTypeFull
+ _bindIoInPlace(iodefClone)
+ iodefClone
}
//