// SPDX-License-Identifier: Apache-2.0 package chisel3.util.experimental import chisel3._ import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} 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] }) } }