From 161938b84013a6c3307abc2707f541deddf487b4 Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Mon, 8 Jun 2020 10:29:39 -0700 Subject: 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 Co-authored-by: Jim Lawson Co-authored-by: Schuyler Eldridge --- .../scala/chisel3/util/experimental/group.scala | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/scala/chisel3/util/experimental/group.scala (limited to 'src/main') 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] + }) + } +} + -- cgit v1.2.3