diff options
Diffstat (limited to 'src/main/scala/firrtl/options/Phase.scala')
| -rw-r--r-- | src/main/scala/firrtl/options/Phase.scala | 88 |
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) } |
