@@ -4,6 +4,7 @@ package chisel3.util.experimental
44
55import chisel3 ._
66import chisel3 .probe .{Probe , RWProbe }
7+ import chisel3 .reflect .DataMirror
78import chisel3 .Data .ProbeInfo
89import chisel3 .experimental .{annotate , requireIsHardware , skipPrefix , BaseModule , ChiselAnnotation , SourceInfo }
910import chisel3 .internal .{Builder , BuilderContextCache , NamedComponent , Namespace , PortBinding }
@@ -217,8 +218,13 @@ object BoringUtils {
217218 genName
218219 }
219220
220- private def boreOrTap [A <: Data ](source : A , createProbe : Option [ProbeInfo ] = None )(implicit si : SourceInfo ): A = {
221- import reflect .DataMirror
221+ private def boreOrTap [A <: Data ](
222+ source : A ,
223+ createProbe : Option [ProbeInfo ] = None ,
224+ isDrive : Boolean = false
225+ )(
226+ implicit si : SourceInfo
227+ ): A = {
222228 def parent (d : Data ): BaseModule = d.topBinding.location.get
223229 def purePortTypeBase = if (createProbe.nonEmpty) Output (chiselTypeOf(source))
224230 else if (DataMirror .hasOuterFlip(source)) Flipped (chiselTypeOf(source))
@@ -263,7 +269,11 @@ object BoringUtils {
263269 // if drilling down, don't drill Probe types
264270 val bore = if (up) module.createSecretIO(purePortType) else module.createSecretIO(Flipped (purePortTypeBase))
265271 module.addSecretIO(bore)
266- conLoc.asInstanceOf [RawModule ].secretConnection(bore, rhs)
272+ if (isDrive) {
273+ conLoc.asInstanceOf [RawModule ].secretConnection(rhs, bore)
274+ } else {
275+ conLoc.asInstanceOf [RawModule ].secretConnection(bore, rhs)
276+ }
267277 bore
268278 }
269279 }
@@ -290,8 +300,8 @@ object BoringUtils {
290300 Builder .error(s " Cannot bore from $source to ${thisModule.name}, as they do not share a least common ancestor " )
291301 }
292302 val (upPath, downPath) = lcaResult.get
293- val lcaSource = drill(source, upPath.dropRight(1 ), upPath.dropRight(1 ), true )
294- val sink = drill(lcaSource, downPath.reverse.tail, downPath.reverse, false )
303+ val lcaSource = drill(source, upPath.dropRight(1 ), upPath.dropRight(1 ), up = ! isDrive )
304+ val sink = drill(lcaSource, downPath.reverse.tail, downPath.reverse, up = isDrive )
295305
296306 if (
297307 createProbe.nonEmpty || DataMirror .hasProbeTypeModifier(purePortTypeBase) ||
@@ -301,7 +311,11 @@ object BoringUtils {
301311 } else {
302312 // Creating a wire to assign the result to. We will return this.
303313 val bore = Wire (purePortTypeBase)
304- thisModule.asInstanceOf [RawModule ].secretConnection(bore, sink)
314+ if (isDrive) {
315+ thisModule.asInstanceOf [RawModule ].secretConnection(sink, bore)
316+ } else {
317+ thisModule.asInstanceOf [RawModule ].secretConnection(bore, sink)
318+ }
305319 bore
306320 }
307321 }
@@ -314,6 +328,17 @@ object BoringUtils {
314328 boreOrTap(source, createProbe = None )
315329 }
316330
331+ /** Access a sink [[Data ]] for driving that may or may not be in the current module.
332+ *
333+ * If the sink is in a child module, than create input ports to allow driving the requested sink.
334+ *
335+ * Note that the sink may not be a probe, and [[rwTap ]] should be used instead.
336+ */
337+ def drive [A <: Data ](sink : A )(implicit si : SourceInfo ): A = {
338+ require(! DataMirror .hasProbeTypeModifier(sink), " cannot drive a probe from BoringUtils.drive" )
339+ boreOrTap(sink, createProbe = None , isDrive = true )
340+ }
341+
317342 /** Access a source [[Data ]] that may or may not be in the current module. If
318343 * this is in a child module, then create read-only probe ports to allow
319344 * access to the requested source.
0 commit comments