diff options
| author | Richard Lin | 2018-03-02 16:40:28 -0800 |
|---|---|---|
| committer | GitHub | 2018-03-02 16:40:28 -0800 |
| commit | 531dd6cb7a91b9bb642368d792e9c5e0c1c72089 (patch) | |
| tree | 378224bf443a21d821d51138e68b458c009950ce | |
| parent | 46553432aaf65cff131e59081d57dabe16c2ab55 (diff) | |
Fix for 792 (#793)
Makes Builder.updateBundleStack a bit stricter in deciding how many stack frames to discard by additionally matching against method names and deleting stack frames at or above the frame currently being inserted.
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 23 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/AutoClonetypeSpec.scala | 15 |
2 files changed, 29 insertions, 9 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 2cb206d4..5e456030 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -173,8 +173,8 @@ private[chisel3] class DynamicContext() { var currentClockAndReset: Option[ClockAndReset] = None val errors = new ErrorLog val namingStack = new internal.naming.NamingStack - // Record the Bundle instance, class name, and reverse stack trace position of open Bundles - val bundleStack: ArrayBuffer[(Bundle, String, Int)] = ArrayBuffer() + // Record the Bundle instance, class name, method name, and reverse stack trace position of open Bundles + val bundleStack: ArrayBuffer[(Bundle, String, String, Int)] = ArrayBuffer() } private[chisel3] object Builder { @@ -247,13 +247,19 @@ private[chisel3] object Builder { // Returns the current stack of open Bundles // Note: elt will NOT have finished construction, its elements cannot be accessed def updateBundleStack(elt: Bundle): Seq[Bundle] = { - val stackClasses = Thread.currentThread().getStackTrace() - .map(_.getClassName) + val stackElts = Thread.currentThread().getStackTrace() .reverse // so stack frame numbers are deterministic across calls + .dropRight(2) // discard Thread.getStackTrace and updateBundleStack + + // Determine where we are in the Bundle stack + val eltClassName = elt.getClass.getName + val eltStackPos = stackElts.map(_.getClassName).lastIndexOf(eltClassName) // Prune the existing Bundle stack of closed Bundles - val pruneLength = dynamicContext.bundleStack.reverse.prefixLength { case (_, cname, pos) => - pos >= stackClasses.size || stackClasses(pos) != cname + // If we know where we are in the stack, discard frames above that + val stackEltsTop = if (eltStackPos >= 0) eltStackPos else stackElts.size + val pruneLength = dynamicContext.bundleStack.reverse.prefixLength { case (_, cname, mname, pos) => + pos >= stackEltsTop || stackElts(pos).getClassName != cname || stackElts(pos).getMethodName != mname } dynamicContext.bundleStack.trimEnd(pruneLength) @@ -261,10 +267,9 @@ private[chisel3] object Builder { val lastStack = dynamicContext.bundleStack.map(_._1).toSeq // Append the current Bundle to the stack, if it's on the stack trace - val eltClassName = elt.getClass.getName - val eltStackPos = stackClasses.lastIndexOf(eltClassName) if (eltStackPos >= 0) { - dynamicContext.bundleStack.append((elt, eltClassName, eltStackPos)) + val stackElt = stackElts(eltStackPos) + dynamicContext.bundleStack.append((elt, eltClassName, stackElt.getMethodName, eltStackPos)) } // Otherwise discard the stack frame, this shouldn't fail noisily diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala index 59ce98b7..6924f8b8 100644 --- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala +++ b/src/test/scala/chiselTests/AutoClonetypeSpec.scala @@ -56,6 +56,12 @@ object CompanionObjectWithBundle { } } +class NestedAnonymousBundle extends Bundle { + val a = Output(new Bundle { + val a = UInt(8.W) + }) +} + // A Bundle with an argument that is also a field. // Not necessarily good style (and not necessarily recommended), but allowed to preserve compatibility. class BundleWithArgumentField(val x: Data, val y: Data) extends Bundle @@ -146,4 +152,13 @@ class AutoClonetypeSpec extends ChiselFlatSpec { io.data := 1.U } } } + + "Nested directioned anonymous Bundles" should "not need clonetype" in { + elaborate { new Module { + val io = IO(new NestedAnonymousBundle) + val a = WireInit(io) + io.a.a := 1.U + } } + } + } |
