diff options
| author | mergify[bot] | 2022-10-23 22:27:06 +0000 |
|---|---|---|
| committer | GitHub | 2022-10-23 22:27:06 +0000 |
| commit | f86c1ff7b39146f23cd1959bcc63dcb3b0b27125 (patch) | |
| tree | 4f443eb311ca5c0fb0fcd769cdee545ef49413a3 /core/src/main/scala/chisel3 | |
| parent | d997acb05e5a307afb7c9ad4c136b9b4e1506efc (diff) | |
Fix for <> to BlackBox.IO with Compatibility Bundles (#2801) (#2803)
MonoConnect.traceFlow now properly handles coerced directions.
Also minor improvement to getClassName especially useful in test case printf debugging.
(cherry picked from commit 3aba755bdcf996c0fbd846d13268fd6641b29e96)
Co-authored-by: Megan Wachs <megan@sifive.com>
Diffstat (limited to 'core/src/main/scala/chisel3')
| -rw-r--r-- | core/src/main/scala/chisel3/Aggregate.scala | 20 | ||||
| -rw-r--r-- | core/src/main/scala/chisel3/internal/BiConnect.scala | 9 | ||||
| -rw-r--r-- | core/src/main/scala/chisel3/internal/MonoConnect.scala | 30 |
3 files changed, 43 insertions, 16 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index aacf0b1c..4fc9b20f 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -1116,7 +1116,12 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio def elements: SeqMap[String, Data] /** Name for Pretty Printing */ - def className: String = this.getClass.getSimpleName + def className: String = try { + this.getClass.getSimpleName + } catch { + // This happens if your class is defined in an object and is anonymous + case e: java.lang.InternalError if e.getMessage == "Malformed class name" => this.getClass.toString + } private[chisel3] override def typeEquivalent(that: Data): Boolean = that match { case that: Record => @@ -1243,10 +1248,15 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record wi "Please see https://github.com/chipsalliance/chisel3#build-your-own-chisel-projects." ) - override def className: String = this.getClass.getSimpleName match { - case name if name.startsWith("$anon$") => "AnonymousBundle" // fallback for anonymous Bundle case - case "" => "AnonymousBundle" // ditto, but on other platforms - case name => name + override def className: String = try { + this.getClass.getSimpleName match { + case name if name.startsWith("$anon$") => "AnonymousBundle" // fallback for anonymous Bundle case + case "" => "AnonymousBundle" // ditto, but on other platforms + case name => name + } + } catch { + // This happens if you have nested objects which your class is defined in + case e: java.lang.InternalError if e.getMessage == "Malformed class name" => this.getClass.toString } /** The collection of [[Data]] diff --git a/core/src/main/scala/chisel3/internal/BiConnect.scala b/core/src/main/scala/chisel3/internal/BiConnect.scala index e8fb2361..74376598 100644 --- a/core/src/main/scala/chisel3/internal/BiConnect.scala +++ b/core/src/main/scala/chisel3/internal/BiConnect.scala @@ -227,9 +227,12 @@ private[chisel3] object BiConnect { context_mod: RawModule ): Unit = { // Verify right has no extra fields that left doesn't have - for ((field, right_sub) <- right_r.elements) { - if (!left_r.elements.isDefinedAt(field)) { - if (connectCompileOptions.connectFieldsMustMatch) { + + // For each field in left, descend with right. + // Don't bother doing this check if we don't expect it to necessarily pass. + if (connectCompileOptions.connectFieldsMustMatch) { + for ((field, right_sub) <- right_r.elements) { + if (!left_r.elements.isDefinedAt(field)) { throw MissingLeftFieldException(field) } } diff --git a/core/src/main/scala/chisel3/internal/MonoConnect.scala b/core/src/main/scala/chisel3/internal/MonoConnect.scala index 31364804..4e762a7c 100644 --- a/core/src/main/scala/chisel3/internal/MonoConnect.scala +++ b/core/src/main/scala/chisel3/internal/MonoConnect.scala @@ -322,21 +322,35 @@ private[chisel3] object MonoConnect { else false } - /** Trace flow from child Data to its parent. */ - @tailrec private[chisel3] def traceFlow(currentlyFlipped: Boolean, data: Data, context_mod: RawModule): Boolean = { - import SpecifiedDirection.{Input => SInput, Flip => SFlip} + /** Trace flow from child Data to its parent. + * + * Returns true if, given the context, + * this signal can be a sink when wantsToBeSink = true, + * or if it can be a source when wantsToBeSink = false. + * Always returns true if the Data does not actually correspond + * to a Port. + */ + @tailrec private[chisel3] def traceFlow( + wantToBeSink: Boolean, + currentlyFlipped: Boolean, + data: Data, + context_mod: RawModule + ): Boolean = { val sdir = data.specifiedDirection - val flipped = sdir == SInput || sdir == SFlip + val coercedFlip = sdir == SpecifiedDirection.Input + val coercedAlign = sdir == SpecifiedDirection.Output + val flipped = sdir == SpecifiedDirection.Flip + val traceFlipped = ((flipped ^ currentlyFlipped) || coercedFlip) && (!coercedAlign) data.binding.get match { - case ChildBinding(parent) => traceFlow(flipped ^ currentlyFlipped, parent, context_mod) + case ChildBinding(parent) => traceFlow(wantToBeSink, traceFlipped, parent, context_mod) case PortBinding(enclosure) => val childPort = enclosure != context_mod - childPort ^ flipped ^ currentlyFlipped + wantToBeSink ^ childPort ^ traceFlipped case _ => true } } - def canBeSink(data: Data, context_mod: RawModule): Boolean = traceFlow(true, data, context_mod) - def canBeSource(data: Data, context_mod: RawModule): Boolean = traceFlow(false, data, context_mod) + def canBeSink(data: Data, context_mod: RawModule): Boolean = traceFlow(true, false, data, context_mod) + def canBeSource(data: Data, context_mod: RawModule): Boolean = traceFlow(false, false, data, context_mod) /** Check whether two aggregates can be bulk connected (<=) in FIRRTL. (MonoConnect case) * |
