Packages

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
Linear Supertypes
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. BoringUtils
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. 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.

  6. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native()
  7. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  8. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  9. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable])
  10. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  11. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  12. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  13. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  14. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  15. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  16. 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.

  17. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  18. 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.

  19. 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.

  20. def toString(): String
    Definition Classes
    AnyRef → Any
  21. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  22. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  23. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()

Deprecated Value Members

  1. 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

  2. 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

  3. 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

Inherited from AnyRef

Inherited from Any

Ungrouped