diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/chisel3/util/experimental/BoringUtils.scala | 95 |
1 files changed, 43 insertions, 52 deletions
diff --git a/src/main/scala/chisel3/util/experimental/BoringUtils.scala b/src/main/scala/chisel3/util/experimental/BoringUtils.scala index c1bfa240..67a6b6d0 100644 --- a/src/main/scala/chisel3/util/experimental/BoringUtils.scala +++ b/src/main/scala/chisel3/util/experimental/BoringUtils.scala @@ -17,14 +17,11 @@ import chisel3.internal.Namespace */ class BoringUtilsException(message: String) extends Exception(message) -/** Utilities for generating synthesizeable cross module references that - * "bore" through the hieararchy. The underlying cross module connects - * are handled by FIRRTL's Wiring Transform - * ([[firrtl.passes.wiring.WiringTransform]]). +/** Utilities for generating synthesizable cross module references that "bore" through the hierarchy. The underlying + * cross module connects are handled by FIRRTL's Wiring Transform ([[firrtl.passes.wiring.WiringTransform]]). * - * 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`: + * 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{}) @@ -40,9 +37,8 @@ class BoringUtilsException(message: String) extends Exception(message) * } * }}} * - * 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: + * 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]] * @@ -50,10 +46,9 @@ class BoringUtilsException(message: String) extends Exception(message) * * ===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`. + * 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 { @@ -66,11 +61,9 @@ class BoringUtilsException(message: String) extends Exception(message) * * ===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`. + * 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 { @@ -96,17 +89,13 @@ class BoringUtilsException(message: String) extends Exception(message) * * ==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. + * 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. + * The automatic generation of hierarchical names relies on a global, mutable namespace. This is currently persistent + * across circuit elaborations. */ object BoringUtils { /* A global namespace for boring ids */ @@ -125,22 +114,24 @@ object BoringUtils { private def checkName(value: String): Boolean = namespace.get.contains(value) /** Add a named source cross module reference - * * @param component source circuit component * @param name unique identifier for this source - * @param dedup enable dedupblication of modules (necessary if other - * instances exist in the design that are not sources) - * @param uniqueName if true, this will use a non-conflicting name from - * the global namespace + * @param disableDedup disable dedupblication of this source component (this should be true if you are trying to wire + * from specific identical sources differently) + * @param uniqueName if true, this will use a non-conflicting name from the global namespace * @return the name used - * @note if a uniqueName is not specified, the returned name may differ - * from the user-provided name + * @note if a uniqueName is not specified, the returned name may differ from the user-provided name */ - def addSource(component: NamedComponent, name: String, dedup: Boolean = false, uniqueName: Boolean = false): String = { + def addSource( + component: NamedComponent, + name: String, + disableDedup: Boolean = false, + uniqueName: Boolean = false): String = { + val id = if (uniqueName) { newName(name) } else { name } val maybeDedup = - if (dedup) { Seq(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(component.toNamed.module) }) } - else { Seq[ChiselAnnotation]() } + if (disableDedup) { Seq(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(component.toNamed.module) }) } + else { Seq[ChiselAnnotation]() } val annotations = Seq(new ChiselAnnotation with RunFirrtlTransform { def toFirrtl = SourceAnnotation(component.toNamed, id) @@ -151,19 +142,20 @@ object BoringUtils { id } - /** Add a named sink cross module reference. Multiple sinks may map to - * the same source. - * + /** Add a named sink cross module reference. Multiple sinks may map to the same source. * @param component sink circuit component * @param name unique identifier for this sink that must resolve to - * @param dedup enable deduplication on sink component (necessary if - * other instances exist in the design that are not sinks) a source - * identifier - * @param forceExists if true, require that the provided `name` paramater - * already exists in the global namespace - * @throws BoringUtilsException if name is expected to exist and it doesn't + * @param disableDedup disable deduplication of this sink component (this should be true if you are trying to wire + * specific, identical sinks differently) + * @param forceExists if true, require that the provided `name` paramater already exists in the global namespace + * @throws BoringUtilsException if name is expected to exist and itdoesn't */ - def addSink(component: InstanceId, name: String, dedup: Boolean = false, forceExists: Boolean = false): Unit = { + def addSink( + component: InstanceId, + name: String, + disableDedup: Boolean = false, + forceExists: Boolean = false): Unit = { + if (forceExists && !checkName(name)) { throw new BoringUtilsException(s"Sink ID '$name' not found in BoringUtils ID namespace") } def moduleName = component.toNamed match { @@ -172,8 +164,8 @@ object BoringUtils { case _ => throw new ChiselException("Can only add a Module or Component sink", null) } val maybeDedup = - if (dedup) { Seq(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(moduleName) }) } - else { Seq[ChiselAnnotation]() } + if (disableDedup) { Seq(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(moduleName) }) } + else { Seq[ChiselAnnotation]() } val annotations = Seq(new ChiselAnnotation with RunFirrtlTransform { def toFirrtl = SinkAnnotation(component.toNamed, name) @@ -182,7 +174,6 @@ object BoringUtils { } /** Connect a source to one or more sinks - * * @param source a source component * @param sinks one or more sink components * @return the name of the signal used to connect the source to the |
