Skip to content

Commit a5df567

Browse files
Allow BoringUtils to use existing port in a closed module (#4484) (#4486)
* fix case ordering when drilling connection * add test (cherry picked from commit 9d58f0d) Co-authored-by: Trevor McKay <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 648366a commit a5df567

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/main/scala/chisel3/util/experimental/BoringUtils.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,10 @@ object BoringUtils {
246246
}
247247
def drill(source: A, path: Seq[BaseModule], connectionLocation: Seq[BaseModule], up: Boolean): A = {
248248
path.zip(connectionLocation).foldLeft(source) {
249-
case (rhs, (module, conLoc)) if (module.isFullyClosed) => boringError(module); DontCare.asInstanceOf[A]
250249
case (rhs, (module, _)) if (up && module == path(0) && isPort(rhs)) => {
251250
rhs
252251
}
252+
case (rhs, (module, conLoc)) if (module.isFullyClosed) => boringError(module); DontCare.asInstanceOf[A]
253253
case (rhs, (module, conLoc)) =>
254254
skipPrefix { // so `lcaSource` isn't in the name of the secret port
255255
if (!up && createProbe.nonEmpty && createProbe.get.writable) {

src/test/scala/chiselTests/BoringUtilsTapSpec.scala

+40
Original file line numberDiff line numberDiff line change
@@ -826,4 +826,44 @@ class BoringUtilsTapSpec extends ChiselFlatSpec with ChiselRunners with Utils wi
826826
val e = the[ChiselException] thrownBy circt.stage.ChiselStage.emitCHIRRTL(new Top)
827827
e.getMessage should include("BoringUtils currently only support identity views")
828828
}
829+
830+
it should "reuse existing port in a closed module" in {
831+
class Foo extends Module {
832+
val io = IO(Output(UInt(32.W)))
833+
val ioProbe = IO(probe.RWProbe(UInt(32.W)))
834+
probe.define(ioProbe, probe.RWProbeValue(io))
835+
io := 0.U
836+
}
837+
838+
class Bar extends Module {
839+
val foo = Module(new Foo)
840+
val ioNames = reflect.DataMirror.modulePorts(foo).map(_._1) // close foo
841+
val io = IO(Output(UInt(32.W)))
842+
io := foo.io
843+
}
844+
845+
class Baz extends Module {
846+
val bar = Module(new Bar)
847+
val reProbe = Wire(probe.RWProbe(UInt(32.W)))
848+
probe.define(reProbe, BoringUtils.rwTap(bar.foo.ioProbe))
849+
probe.forceInitial(reProbe, 1.U)
850+
}
851+
852+
val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Baz)
853+
matchesAndOmits(chirrtl)(
854+
"module Foo :",
855+
"output io : UInt<32>",
856+
"output ioProbe : RWProbe<UInt<32>>",
857+
"define ioProbe = rwprobe(io)",
858+
"module Bar :",
859+
"inst foo of Foo",
860+
"output bore : RWProbe<UInt<32>>",
861+
"define bore = foo.ioProbe",
862+
"module Baz :",
863+
"inst bar of Bar",
864+
"wire reProbe : RWProbe<UInt<32>>",
865+
"define reProbe = bar.bore",
866+
"force_initial(reProbe, UInt<32>(0h1))"
867+
)()
868+
}
829869
}

0 commit comments

Comments
 (0)