object BoringUtils
Utilities for generating synthesizable cross module references that "bore" through the hierarchy. The underlying cross module connects are handled by FIRRTL's Wiring Transform.
Consider the following example where you want to connect a component in one module to a component in another. Module
Constant
has a wire tied to 42
and Expect
will assert unless connected to 42
:
class Constant extends Module { val io = IO(new Bundle{}) val x = Wire(UInt(6.W)) x := 42.U } class Expect extends Module { val io = IO(new Bundle{}) val y = Wire(UInt(6.W)) y := 0.U // This assertion will fail unless we bore! chisel3.assert(y === 42.U, "y should be 42 in module Expect") }
We can then connect x
to y
using BoringUtils without modifiying the Chisel IO of Constant
, Expect
, or
modules that may instantiate them. There are two approaches to do this:
1. Hierarchical boring using BoringUtils.bore
2. Non-hierarchical boring using BoringUtils.addSink/BoringUtils.addSource
Hierarchical Boring
Hierarchical boring involves connecting one sink instance to another source instance in a parent module. Below,
module Top
contains an instance of Constant
and Expect
. Using BoringUtils.bore, we can connect
constant.x
to expect.y
.
class Top extends Module { val io = IO(new Bundle{}) val constant = Module(new Constant) val expect = Module(new Expect) BoringUtils.bore(constant.x, Seq(expect.y)) }
Bottom-up boring involves boring a sink in a child instance to the current module, where it can be assigned from.
Using BoringUtils.bore, we can connect from constant.x
to mywire
.
class Top extends Module { val io = IO(new Bundle { val foo = UInt(3.W) }) val constant = Module(new Constant) io.foo := BoringUtils.bore(constant.x) }
Non-hierarchical Boring
Non-hierarchical boring involves connections from sources to sinks that cannot see each other. Here, x
is
described as a source and given a name, uniqueId
, and y
is described as a sink with the same name. This is
equivalent to the hierarchical boring example above, but requires no modifications to Top
.
class Constant extends Module { val io = IO(new Bundle{}) val x = Wire(UInt(6.W)) x := 42.U BoringUtils.addSource(x, "uniqueId") } class Expect extends Module { val io = IO(new Bundle{}) val y = Wire(UInt(6.W)) y := 0.U // This assertion will fail unless we bore! chisel3.assert(y === 42.U, "y should be 42 in module Expect") BoringUtils.addSink(y, "uniqueId") } class Top extends Module { val io = IO(new Bundle{}) val constant = Module(new Constant) val expect = Module(new Expect) }
Comments
Both hierarchical and non-hierarchical boring emit FIRRTL annotations that describe sources and sinks. These are
matched by a name
key that indicates they should be wired together. Hierarchical boring safely generates this name
automatically. Non-hierarchical boring unsafely relies on user input to generate this name. Use of non-hierarchical
naming may result in naming conflicts that the user must handle.
The automatic generation of hierarchical names relies on a global, mutable namespace. This is currently persistent across circuit elaborations.
- Source
- BoringUtils.scala
- Alphabetic
- By Inheritance
- BoringUtils
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def bore[A <: Data](source: A)(implicit si: SourceInfo): A
Access a source Data that may or may not be in the current module.
Access a source Data that may or may not be in the current module. If this is in a child module, then create ports to allow access to the requested source.
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- def rwTap[A <: Data](source: A)(implicit si: SourceInfo): A
Access a source Data that may or may not be in the current module.
Access a source Data that may or may not be in the current module. If this is in a child module, then create write-only probe ports to allow access to the requested source. Supports downward accesses only.
Returns a probe Data type.
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def tap[A <: Data](source: A)(implicit si: SourceInfo): A
Access a source Data that may or may not be in the current module.
Access a source Data that may or may not be in the current module. If this is in a child module, then create read-only probe ports to allow access to the requested source.
Returns a probe Data type.
- def tapAndRead[A <: Data](source: A)(implicit si: SourceInfo): A
Access a source Data that may or may not be in the current module.
Access a source Data that may or may not be in the current module. If this is in a child module, then create read-only probe ports to allow access to the requested source.
Returns a non-probe Data type.
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
Deprecated Value Members
- def addSink(component: InstanceId, name: String, disableDedup: Boolean = false, forceExists: Boolean = false): Unit
Add a named sink cross module reference.
Add a named sink cross module reference. Multiple sinks may map to the same source.
- component
sink circuit component
- name
unique identifier for this sink that must resolve to
- disableDedup
disable deduplication of this sink component (this should be true if you are trying to wire specific, identical sinks differently)
- forceExists
if true, require that the provided
name
parameter already exists in the global namespace
- Annotations
- @deprecated
- Deprecated
(Since version Chisel 6.0) Please use the new Boring API instead (BoringUtils.bore(source)). This will be removed in Chisel 7.0
- Exceptions thrown
BoringUtilsException
if name is expected to exist and it doesn't
- def addSource(component: NamedComponent, name: String, disableDedup: Boolean = false, uniqueName: Boolean = false): String
Add a named source cross module reference
Add a named source cross module reference
- component
source circuit component
- name
unique identifier for this source
- disableDedup
disable deduplication of this source component (this should be true if you are trying to wire from specific identical sources differently)
- uniqueName
if true, this will use a non-conflicting name from the global namespace
- returns
the name used
- Annotations
- @deprecated
- Deprecated
(Since version Chisel 6.0) Please use the new Boring API instead (BoringUtils.bore(source)). This will be removed in Chisel 7.0
- Note
if a uniqueName is not specified, the returned name may differ from the user-provided name
- def bore(source: Data, sinks: Seq[Data]): String
Connect a source to one or more sinks
Connect a source to one or more sinks
- source
a source component
- sinks
one or more sink components
- returns
the name of the signal used to connect the source to the sinks
- Annotations
- @deprecated
- Deprecated
(Since version Chisel 6.0) Please use the new Boring API instead (BoringUtils.bore(source)). This will be removed in Chisel 7.0
- Note
the returned name will be based on the name of the source component