aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/options/Phase.scala
blob: 34739053882c1e1494a1a0bb7ecd205ff741000c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// See LICENSE for license details.

package firrtl.options

import firrtl.AnnotationSeq
import firrtl.annotations.DeletedAnnotation

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

}

/** A [[TransformLike]] that internally ''translates'' the input type to some other type, transforms the internal type,
  * and converts back to the original type.
  *
  * 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
  */
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

  /** Convert the input object to the internal type, transform the internal type, and convert back to the original type
    */
  final def transform(a: A): A = internalTransform(a)

}