aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/options/Phase.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/firrtl/options/Phase.scala')
-rw-r--r--src/main/scala/firrtl/options/Phase.scala88
1 files changed, 80 insertions, 8 deletions
diff --git a/src/main/scala/firrtl/options/Phase.scala b/src/main/scala/firrtl/options/Phase.scala
index 22715bc2..a660d08a 100644
--- a/src/main/scala/firrtl/options/Phase.scala
+++ b/src/main/scala/firrtl/options/Phase.scala
@@ -3,18 +3,90 @@
package firrtl.options
import firrtl.AnnotationSeq
+import firrtl.annotations.DeletedAnnotation
-/** A transformation of an [[AnnotationSeq]]
+import logger.LazyLogging
+
+import scala.collection.mutable
+
+/** A polymorphic mathematical transform
+ * @tparam A the transformed type
+ */
+trait TransformLike[A] extends LazyLogging {
+
+ /** An identifier of this [[TransformLike]] that can be used for logging and informational printing */
+ def name: String
+
+ /** A mathematical transform on some type
+ * @param a an input object
+ * @return an output object of the same type
+ */
+ def transform(a: A): A
+
+}
+
+/** A mathematical transformation of an [[AnnotationSeq]].
+ *
+ * A [[Phase]] forms one unit in the Chisel/FIRRTL Hardware Compiler Framework (HCF). The HCF is built from a sequence
+ * of [[Phase]]s applied to an [[AnnotationSeq]]. Note that a [[Phase]] may consist of multiple phases internally.
+ */
+abstract class Phase extends TransformLike[AnnotationSeq] {
+
+ /** The name of this [[Phase]]. This will be used to generate debug/error messages or when deleting annotations. This
+ * will default to the `simpleName` of the class.
+ * @return this phase's name
+ * @note Override this with your own implementation for different naming behavior.
+ */
+ lazy val name: String = this.getClass.getName
+
+ /** Perform the transform of [[transform]] on an [[firrtl.AnnotationSeq AnnotationSeq]] and add
+ * [[firrtl.annotations.DeletedAnnotation DeletedAnnotation]]s for any deleted [[firrtl.annotations.Annotation
+ * Annotation]]s.
+ * @param a
+ */
+ final def runTransform(annotations: AnnotationSeq): AnnotationSeq = {
+ val ax = transform(annotations)
+
+ val (in, out) = (mutable.LinkedHashSet() ++ annotations, mutable.LinkedHashSet() ++ ax)
+
+ (in -- out).map {
+ case DeletedAnnotation(n, a) => DeletedAnnotation(s"$n+$name", a)
+ case a => DeletedAnnotation(name, a)
+ }.toSeq ++ ax
+ }
+
+}
+
+/** A [[TransformLike]] that internally ''translates'' the input type to some other type, transforms the internal type,
+ * and converts back to the original type.
*
- * A [[Phase]] forms one block in the Chisel/FIRRTL Hardware Compiler Framework (HCF). Note that a [[Phase]] may
- * consist of multiple phases internally.
+ * This is intended to be used to insert a [[TransformLike]] parameterized by type `B` into a sequence of
+ * [[TransformLike]]s parameterized by type `A`.
+ * @tparam A the type of the [[TransformLike]]
+ * @tparam B the internal type
*/
-abstract class Phase {
+trait Translator[A, B] { this: TransformLike[A] =>
+
+ /** A method converting type `A` into type `B`
+ * @param an object of type `A`
+ * @return an object of type `B`
+ */
+ protected implicit def aToB(a: A): B
+
+ /** A method converting type `B` back into type `A`
+ * @param an object of type `B`
+ * @return an object of type `A`
+ */
+ protected implicit def bToA(b: B): A
+
+ /** A transform on an internal type
+ * @param b an object of type `B`
+ * @return an object of type `B`
+ */
+ protected def internalTransform(b: B): B
- /** A transformation of an [[AnnotationSeq]]
- * @param annotations some annotations
- * @return transformed annotations
+ /** Convert the input object to the internal type, transform the internal type, and convert back to the original type
*/
- def transform(annotations: AnnotationSeq): AnnotationSeq
+ final def transform(a: A): A = internalTransform(a)
}