Skip to content

Commit

Permalink
In BoringUtils.drive, don't bore into the final module for inputs. (#…
Browse files Browse the repository at this point in the history
…3998)

This follows up on #3960
to address the behavior at the final module for the sink being
driven. We already have special handling for boring out from the
original source, and we need the inverse here. When we reach the final
sink, if it is an input port, we should use it, rather than boring
into the module and connecting to it.
  • Loading branch information
mikeurbach authored Apr 15, 2024
1 parent 9b40344 commit a9b1017
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/main/scala/chisel3/util/experimental/BoringUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ object BoringUtils {
case Some(PortBinding(_)) => true
case _ => false
}
def isDriveDone(d: Data): Boolean = {
isDrive && isPort(d) && DataMirror.directionOf(d) == ActualDirection.Input
}
def boringError(module: BaseModule): Unit = {
(module.fullyClosedErrorMessages ++ Seq(
(si, s"Can only bore into modules that are not fully closed: ${module.name} was fully closed")
Expand All @@ -254,8 +257,9 @@ object BoringUtils {
path.zip(connectionLocation).foldLeft(source) {
case (rhs, (module, conLoc)) if (module.isFullyClosed) => boringError(module); DontCare.asInstanceOf[A]
case (rhs, (module, _))
if (up && module == path(0) && isPort(rhs) && (!createProbe.nonEmpty || !createProbe.get.writable)) => {
// When drilling from the original source, if it's already a port just return it.
if ((up || isDriveDone(rhs)) && module == path(0) && isPort(rhs) &&
(!createProbe.nonEmpty || !createProbe.get.writable)) => {
// When drilling from the original source, or driving to the sink, if it's already a port just return it.
// As an exception, insist rwTaps are done from within the module and exported out.
rhs
}
Expand Down
49 changes: 49 additions & 0 deletions src/test/scala/chiselTests/BoringUtilsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -437,4 +437,53 @@ class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners with Utils with
"propassign foo.bore, Integer(1)"
)()
}

it should "bore to the final instance, but not into it, for inputs" in {
class Foo extends RawModule {
val a = IO(Input(Property[Int]()))
}

class Bar extends RawModule {
val foo = Module(new Foo)
}

class Baz extends RawModule {
val bar = Module(new Bar)

BoringUtils.drive(bar.foo.a) := Property(1)
}

val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Baz)

matchesAndOmits(chirrtl)(
"input bore",
"propassign foo.a, bore",
"propassign bar.bore, Integer(1)"
)()
}

it should "bore into the final instance for outputs" in {
class Foo extends RawModule {
val a = IO(Output(Property[Int]()))
}

class Bar extends RawModule {
val foo = Module(new Foo)
}

class Baz extends RawModule {
val bar = Module(new Bar)

BoringUtils.drive(bar.foo.a) := Property(1)
}

val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Baz)

matchesAndOmits(chirrtl)(
"input bore",
"propassign a, bore",
"propassign foo.bore, bore",
"propassign bar.bore, Integer(1)"
)()
}
}

0 comments on commit a9b1017

Please sign in to comment.