diff options
| author | Richard Lin | 2018-02-07 13:49:15 -0800 |
|---|---|---|
| committer | GitHub | 2018-02-07 13:49:15 -0800 |
| commit | 254597c125bda06e041a4a241177e959200ce8f7 (patch) | |
| tree | d67e6bb0212c17ac19e095aff6d2edb8b92e6bf9 /chiselFrontend/src/main/scala/chisel3/core/Module.scala | |
| parent | 7be9b1c681558695b95fccb22a60c34101c86118 (diff) | |
Cloning IO with compatibility 🦆 (#754)
Changes the API such that IO(...) clones. All Bundles will need to be clone-able, but auto clone type is expected to handle most cases.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Module.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Module.scala | 57 |
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 } // |
