diff options
| author | Jack Koenig | 2018-02-28 17:40:53 -0800 |
|---|---|---|
| committer | GitHub | 2018-02-28 17:40:53 -0800 |
| commit | 46553432aaf65cff131e59081d57dabe16c2ab55 (patch) | |
| tree | 2a64125046b36808a5a89c18f98204394c27ccd8 /chiselFrontend/src/main/scala/chisel3/core/Annotation.scala | |
| parent | 97871178cb511063965f971b768f91c289c4776f (diff) | |
Refactor Annotations (#767)
* Generalize ChiselAnnotation
This allows us to delay creation of Annotations till elaboration is
complete. Also update all annotation-related code.
* Add RunFirrtlTransform
Use a Chisel-specific RunFirrtlTransform API to preserve behavior of old
ChiselAnnotation (now called ChiselLegacyAnnotation)
* Use unique test directories in ChiselRunners.compile
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Annotation.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Annotation.scala | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala b/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala new file mode 100644 index 00000000..cfee67cb --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala @@ -0,0 +1,90 @@ +// See LICENSE for license details. + +package chisel3.core + +import scala.language.existentials + +import chisel3.internal.{Builder, InstanceId} +import firrtl.Transform +import firrtl.annotations.{Annotation, CircuitName, ComponentName, ModuleName} +import firrtl.transforms.DontTouchAnnotation + +/** Interface for Annotations in Chisel + * + * Defines a conversion to a corresponding FIRRTL Annotation + */ +trait ChiselAnnotation { + /** Conversion to FIRRTL Annotation */ + def toFirrtl: Annotation +} +object ChiselAnnotation { + @deprecated("Write a custom ChiselAnnotation subclass instead", "3.1") + def apply(component: InstanceId, transformClass: Class[_ <: Transform], value: String) = + ChiselLegacyAnnotation(component, transformClass, value) + @deprecated("Write a custom ChiselAnnotation subclass instead", "3.1") + def unapply(anno: ChiselAnnotation): Option[(InstanceId, Class[_ <: Transform], String)] = + anno match { + case ChiselLegacyAnnotation(c, t, v) => Some(c, t, v) + case _ => None + } +} + +/** Mixin for [[ChiselAnnotation]] that instantiates an associated FIRRTL Transform when this + * Annotation is present during a run of [[chisel3.Driver.execute]]. Automatic Transform + * instantiation is *not* supported when the Circuit and Annotations are serialized before invoking + * FIRRTL. + */ +// TODO There should be a FIRRTL API for this instead +trait RunFirrtlTransform extends ChiselAnnotation { + def transformClass: Class[_ <: Transform] +} + +// This exists for implementation reasons, we don't want people using this type directly +final case class ChiselLegacyAnnotation private[chisel3] ( + component: InstanceId, + transformClass: Class[_ <: Transform], + value: String) extends ChiselAnnotation with RunFirrtlTransform { + def toFirrtl: Annotation = Annotation(component.toNamed, transformClass, value) +} +private[chisel3] object ChiselLegacyAnnotation + +object annotate { // scalastyle:ignore object.name + def apply(anno: ChiselAnnotation): Unit = { + Builder.annotations += anno + } +} + +/** Marks that a signal should not be removed by Chisel and Firrtl optimization passes + * + * @example {{{ + * class MyModule extends Module { + * val io = IO(new Bundle { + * val a = Input(UInt(32.W)) + * val b = Output(UInt(32.W)) + * }) + * io.b := io.a + * val dead = io.a +% 1.U // normally dead would be pruned by DCE + * dontTouch(dead) // Marking it as such will preserve it + * } + * }}} + * + * @note Calling this on [[Data]] creates an annotation that Chisel emits to a separate annotations + * file. This file must be passed to FIRRTL independently of the `.fir` file. The execute methods + * in [[chisel3.Driver]] will pass the annotations to FIRRTL automatically. + */ +object dontTouch { // scalastyle:ignore object.name + /** Marks a signal to be preserved in Chisel and Firrtl + * + * @note Requires the argument to be bound to hardware + * @param data The signal to be marked + * @return Unmodified signal `data` + */ + def apply[T <: Data](data: T)(implicit compileOptions: CompileOptions): T = { + if (compileOptions.checkSynthesizable) { + requireIsHardware(data, "Data marked dontTouch") + } + annotate(new ChiselAnnotation { def toFirrtl = DontTouchAnnotation(data.toNamed) }) + data + } +} + |
