diff options
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala | 25 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Data.scala | 7 |
2 files changed, 32 insertions, 0 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index d4d67018..da14cefd 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -5,6 +5,7 @@ package chisel3.core import scala.collection.immutable.ListMap import scala.collection.mutable.{ArrayBuffer, HashSet, LinkedHashMap} import scala.language.experimental.macros +import scala.util.Try import chisel3.internal._ import chisel3.internal.Builder.pushCommand @@ -574,6 +575,30 @@ class Bundle(implicit compileOptions: CompileOptions) extends Record { Builder.exception(s"Unable to automatically infer cloneType on $this: $desc") } + // Check if the bundle is an instance of an inner class by examining + // whether it has one one-argument constructor taking a type matching the enclosing class + if (this.getClass.getConstructors.size == 1) { + val aggClass = this.getClass + val constr = aggClass.getConstructors.head + val argTypes = constr.getParameterTypes + val outerClass = aggClass.getEnclosingClass + if (argTypes.size == 1 && outerClass != null) { + // attempt to clone using "$outer" + var clone: Option[this.type] = + Try[this.type](constr.newInstance(aggClass.getDeclaredField("$outer").get(this)).asInstanceOf[this.type]).toOption + if (clone.isEmpty) { + // fall back to outerModule field + clone = Try[this.type](constr.newInstance(outerModule.get).asInstanceOf[this.type]).toOption + } + clone.foreach(_.outerModule = this.outerModule) + if (clone.isDefined) { + return clone.get + } else { + reflectError("non-trivial inner Bundle class") + } + } + } + // Try Scala reflection import scala.reflect.runtime.universe._ diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 19adf01b..d84a86e9 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -208,6 +208,13 @@ abstract class Data extends HasId { } } + // If this Data is an instance of an inner class, record enclosing class + // This is only used for cloneType! + private[core] var outerModule: Option[BaseModule] = + (Option(this.getClass.getEnclosingClass) zip Builder.currentModule) + .find({ case (c, m) => c.isAssignableFrom(m.getClass) }) + .map({ case (_, m) => m }) + // User-specified direction, local at this node only. // Note that the actual direction of this node can differ from child and parent specifiedDirection. private var _specifiedDirection: SpecifiedDirection = SpecifiedDirection.Unspecified |
