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.scala28
1 files changed, 27 insertions, 1 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
index b512ed75..0f081daf 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
@@ -219,8 +219,34 @@ abstract class BaseModule extends HasId {
*/
protected def IO[T<:Data](iodef: T): iodef.type = {
require(!_closed, "Can't add more ports after module close")
+ requireIsChiselType(iodef, "io type")
+
+ // 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
+ // Bundles defined in compatibility mode.
+ // This recursively walks the tree, and assigns directions if no explicit
+ // direction given by upper-levels (override Input / Output) AND element is
+ // directly inside a compatibility Bundle determined by compile options.
+ def assignCompatDir(data: Data, insideCompat: Boolean): Unit = {
+ data match {
+ case data: Element if insideCompat => data._assignCompatibilityExplicitDirection
+ case data: Element => // Not inside a compatibility Bundle, nothing to be done
+ case data: Aggregate => data.userDirection match {
+ // Recurse into children to ensure explicit direction set somewhere
+ case UserDirection.Unspecified | UserDirection.Flip => data match {
+ case data: Record if (!data.compileOptions.dontAssumeDirectionality) =>
+ data.getElements.foreach(assignCompatDir(_, true))
+ case _ => data.getElements.foreach(assignCompatDir(_, false))
+ }
+ case UserDirection.Input | UserDirection.Output => // forced assign, nothing to do
+ }
+ }
+ }
+ assignCompatDir(iodef, false)
+
// Bind each element of the iodef to being a Port
- Binding.bind(iodef, PortBinder(this), "Error: iodef")
+ iodef.bind(PortBinding(this))
_ports += iodef
iodef
}