summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Lin2018-03-02 16:40:28 -0800
committerGitHub2018-03-02 16:40:28 -0800
commit531dd6cb7a91b9bb642368d792e9c5e0c1c72089 (patch)
tree378224bf443a21d821d51138e68b458c009950ce
parent46553432aaf65cff131e59081d57dabe16c2ab55 (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.scala23
-rw-r--r--src/test/scala/chiselTests/AutoClonetypeSpec.scala15
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
+ } }
+ }
+
}