summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/util/experimental
diff options
context:
space:
mode:
authorAdam Izraelevitz2020-06-08 10:29:39 -0700
committerGitHub2020-06-08 17:29:39 +0000
commit161938b84013a6c3307abc2707f541deddf487b4 (patch)
treeadbc8f1ca82672127fb9c484e2d10e59a3de4a05 /src/main/scala/chisel3/util/experimental
parent803ccbb705288a90c2020a1e13ec714f25ffcb13 (diff)
Grouping Chisel API (#1073)
* Added group chisel API * Removed println * Added scaladoc * Added more tests * Cleaned spacing and removed println Co-authored-by: Chick Markley <chick@qrhino.com> Co-authored-by: Jim Lawson <ucbjrl@berkeley.edu> Co-authored-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src/main/scala/chisel3/util/experimental')
-rw-r--r--src/main/scala/chisel3/util/experimental/group.scala67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/main/scala/chisel3/util/experimental/group.scala b/src/main/scala/chisel3/util/experimental/group.scala
new file mode 100644
index 00000000..87214ca9
--- /dev/null
+++ b/src/main/scala/chisel3/util/experimental/group.scala
@@ -0,0 +1,67 @@
+// See LICENSE for license details.
+
+package chisel3.util.experimental
+
+import chisel3._
+import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate}
+import chisel3.internal.requireIsHardware
+import firrtl.Transform
+import firrtl.transforms.{GroupAnnotation, GroupComponents}
+
+/** Marks that a module to be ignored in Dedup Transform in Firrtl pass
+ *
+ * @example {{{
+ * class MyModule extends Module {
+ * val io = IO(new Bundle{
+ * val a = Input(Bool())
+ * val b = Output(Bool())
+ * })
+ * val reg1 = RegInit(0.U)
+ * reg1 := io.a
+ * val reg2 = RegNext(reg1)
+ * io.b := reg2
+ * group(Seq(reg1, reg2), "DosRegisters", "doubleReg")
+ * }
+ * }}}
+ *
+ * @note Intermediate wires will get pulled into the new instance, but intermediate registers will not
+ * because they are also connected to their module's clock port. This means that if you want
+ * a register to be included in a group, it must be explicitly referred to in the input list.
+ */
+object group {
+
+ /** Marks a set of components (and their interconnected components) to be included in a new
+ * instance hierarchy.
+ *
+ * @note Intermediate wires will get pulled into the new instance, but intermediate registers will not
+ * because they are also connected to their module's clock port. This means that if you want
+ * a register to be included in a group, it must be explicitly referred to in the input list.
+ *
+ * @param components components in this group
+ * @param newModule suggested name of the new module
+ * @param newInstance suggested name of the instance of the new module
+ * @param outputSuffix suggested suffix of any output ports of the new module
+ * @param inputSuffix suggested suffix of any input ports of the new module
+ * @param compileOptions necessary for backwards compatibility
+ * @tparam T Parent type of input components
+ */
+ def apply[T <: Data](
+ components: Seq[T],
+ newModule: String,
+ newInstance: String,
+ outputSuffix: Option[String] = None,
+ inputSuffix: Option[String] = None
+ )(implicit compileOptions: CompileOptions): Unit = {
+ if (compileOptions.checkSynthesizable) {
+ components.foreach { data =>
+ requireIsHardware(data, s"Component ${data.toString} is marked to group, but is not bound.")
+ }
+ }
+ annotate(new ChiselAnnotation with RunFirrtlTransform {
+ def toFirrtl = GroupAnnotation(components.map(_.toNamed), newModule, newInstance, outputSuffix, inputSuffix)
+
+ override def transformClass: Class[_ <: Transform] = classOf[GroupComponents]
+ })
+ }
+}
+