Object

chisel3.util.experimental

BoringUtils

Related Doc: package experimental

Permalink

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 exmple 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

Hierarchcical boring involves connecting one sink instance to another source instance in a parent module. Below, module Top contains an instance of Cosntant 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))
}
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. Hierarhical 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. All

Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  4. def addSink(component: internal.InstanceId, name: String, disableDedup: Boolean = false, forceExists: Boolean = false): Unit

    Permalink

    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 paramater already exists in the global namespace

    Exceptions thrown

    BoringUtilsException if name is expected to exist and itdoesn't

  5. def addSource(component: NamedComponent, name: String, disableDedup: Boolean = false, uniqueName: Boolean = false): String

    Permalink

    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 dedupblication 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

    Note

    if a uniqueName is not specified, the returned name may differ from the user-provided name

  6. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  7. def bore(source: Data, sinks: Seq[Data]): String

    Permalink

    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

    Note

    the returned name will be based on the name of the source component

  8. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  9. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  10. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  11. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  12. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  13. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  14. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  15. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  16. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  17. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  18. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  19. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  20. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  21. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  22. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )

Inherited from AnyRef

Inherited from Any

Ungrouped