diff options
9 files changed, 44 insertions, 24 deletions
diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index 9f8087bf..ede9ccc6 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -14,6 +14,7 @@ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{InstTransform, SourceInfo, UnlocatableSourceInfo} import chisel3.experimental.BaseModule import _root_.firrtl.annotations.{IsModule, ModuleName, ModuleTarget} +import _root_.firrtl.AnnotationSeq object Module extends SourceInfoDoc { /** A wrapper method that all Module instantiations must be wrapped in diff --git a/core/src/main/scala/chisel3/aop/Aspect.scala b/core/src/main/scala/chisel3/aop/Aspect.scala index 59add417..be9b8975 100644 --- a/core/src/main/scala/chisel3/aop/Aspect.scala +++ b/core/src/main/scala/chisel3/aop/Aspect.scala @@ -12,6 +12,10 @@ import firrtl.AnnotationSeq * @tparam T Type of top-level module */ abstract class Aspect[T <: RawModule] extends Annotation with Unserializable with NoTargetAnnotation { + /** variable to save [[AnnotationSeq]] from [[chisel3.stage.phases.AspectPhase]] + * to be used at [[chisel3.aop.injecting.InjectorAspect]], exposes annotations to [[chisel3.internal.DynamicContext]] + */ + private[aop] var annotationsInAspect: AnnotationSeq = Seq() /** Convert this Aspect to a seq of FIRRTL annotation * @param top * @return @@ -22,7 +26,8 @@ abstract class Aspect[T <: RawModule] extends Annotation with Unserializable wit * @param top * @return */ - private[chisel3] def resolveAspect(top: RawModule): AnnotationSeq = { + private[chisel3] def resolveAspect(top: RawModule, remainingAnnotations: AnnotationSeq): AnnotationSeq = { + annotationsInAspect = remainingAnnotations toAnnotation(top.asInstanceOf[T]) } } diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala index 31d4666c..e95384cd 100644 --- a/core/src/main/scala/chisel3/internal/Builder.scala +++ b/core/src/main/scala/chisel3/internal/Builder.scala @@ -9,7 +9,8 @@ import chisel3.experimental._ import chisel3.internal.firrtl._ import chisel3.internal.naming._ import _root_.firrtl.annotations.{CircuitName, ComponentName, IsMember, ModuleName, Named, ReferenceTarget} -import _root_.firrtl.annotations.AnnotationUtils.{validComponentName} +import _root_.firrtl.annotations.AnnotationUtils.validComponentName +import _root_.firrtl.AnnotationSeq import chisel3.internal.Builder.Prefix import logger.LazyLogging @@ -305,7 +306,7 @@ private[chisel3] class ChiselContext() { var prefixStack: Prefix = Nil } -private[chisel3] class DynamicContext() { +private[chisel3] class DynamicContext(val annotationSeq: AnnotationSeq) { val globalNamespace = Namespace.empty val components = ArrayBuffer[Component]() val annotations = ArrayBuffer[ChiselAnnotation]() @@ -364,6 +365,7 @@ private[chisel3] object Builder extends LazyLogging { def globalNamespace: Namespace = dynamicContext.globalNamespace def components: ArrayBuffer[Component] = dynamicContext.components def annotations: ArrayBuffer[ChiselAnnotation] = dynamicContext.annotations + def annotationSeq: AnnotationSeq = dynamicContext.annotationSeq def namingStack: NamingStack = dynamicContext.namingStack // Puts a prefix string onto the prefix stack @@ -632,11 +634,6 @@ private[chisel3] object Builder extends LazyLogging { } } - - def build[T <: RawModule](f: => T): (Circuit, T) = { - build(f, new DynamicContext()) - } - private [chisel3] def build[T <: RawModule](f: => T, dynamicContext: DynamicContext): (Circuit, T) = { dynamicContextVar.withValue(Some(dynamicContext)) { checkScalaVersion() diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala index 39590b93..170bfbad 100644 --- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala +++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala @@ -54,7 +54,7 @@ abstract class InjectorAspect[T <: RawModule, M <: RawModule]( * @return */ final def toAnnotation(modules: Iterable[M], circuit: String, moduleNames: Seq[String]): AnnotationSeq = { - val dynamicContext = new DynamicContext() + val dynamicContext = new DynamicContext(annotationsInAspect) // Add existing module names into the namespace. If injection logic instantiates new modules // which would share the same name, they will get uniquified accordingly moduleNames.foreach { n => diff --git a/src/main/scala/chisel3/stage/ChiselAnnotations.scala b/src/main/scala/chisel3/stage/ChiselAnnotations.scala index 04246fc5..b071c60f 100644 --- a/src/main/scala/chisel3/stage/ChiselAnnotations.scala +++ b/src/main/scala/chisel3/stage/ChiselAnnotations.scala @@ -56,11 +56,7 @@ case class ChiselGeneratorAnnotation(gen: () => RawModule) extends NoTargetAnnot /** Run elaboration on the Chisel module generator function stored by this [[firrtl.annotations.Annotation]] */ - def elaborate: AnnotationSeq = { - val (circuit, dut) = Builder.build(Module(gen())) - Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut)) - } - + def elaborate: AnnotationSeq = (new chisel3.stage.phases.Elaborate).transform(Seq(this)) } object ChiselGeneratorAnnotation extends HasShellOptions { diff --git a/src/main/scala/chisel3/stage/phases/AspectPhase.scala b/src/main/scala/chisel3/stage/phases/AspectPhase.scala index 1a27b8fa..72965861 100644 --- a/src/main/scala/chisel3/stage/phases/AspectPhase.scala +++ b/src/main/scala/chisel3/stage/phases/AspectPhase.scala @@ -29,7 +29,7 @@ class AspectPhase extends Phase { case other => Seq(other) } if(dut.isDefined) { - val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get) } + val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get, remainingAnnotations) } remainingAnnotations ++ newAnnotations } else annotations } diff --git a/src/main/scala/chisel3/stage/phases/Elaborate.scala b/src/main/scala/chisel3/stage/phases/Elaborate.scala index df39b66b..e8f2623e 100644 --- a/src/main/scala/chisel3/stage/phases/Elaborate.scala +++ b/src/main/scala/chisel3/stage/phases/Elaborate.scala @@ -2,15 +2,13 @@ package chisel3.stage.phases -import java.io.{PrintWriter, StringWriter} - -import chisel3.ChiselException -import chisel3.internal.ErrorLog +import chisel3.Module import chisel3.internal.ExceptionHelpers.ThrowableHelpers -import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOptions} +import chisel3.internal.{Builder, DynamicContext} +import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselOptions, DesignAnnotation} import firrtl.AnnotationSeq +import firrtl.options.Phase import firrtl.options.Viewer.view -import firrtl.options.{OptionsException, Phase} /** Elaborate all [[chisel3.stage.ChiselGeneratorAnnotation]]s into [[chisel3.stage.ChiselCircuitAnnotation]]s. */ @@ -22,8 +20,9 @@ class Elaborate extends Phase { override def invalidates(a: Phase) = false def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap { - case a: ChiselGeneratorAnnotation => try { - a.elaborate + case ChiselGeneratorAnnotation(gen) => try { + val (circuit, dut) = Builder.build(Module(gen()), new DynamicContext(annotations)) + Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut)) } catch { /* if any throwable comes back and we're in "stack trace trimming" mode, then print an error and trim the stack trace */ diff --git a/src/main/scala/chisel3/util/experimental/getAnnotations.scala b/src/main/scala/chisel3/util/experimental/getAnnotations.scala new file mode 100644 index 00000000..dc9b75ee --- /dev/null +++ b/src/main/scala/chisel3/util/experimental/getAnnotations.scala @@ -0,0 +1,9 @@ +package chisel3.util.experimental + +import chisel3.internal.Builder +import firrtl.AnnotationSeq + +object getAnnotations { + /** Returns the global Annotations */ + def apply(): AnnotationSeq = Builder.annotationSeq +} diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index 932c94a5..bc9c524a 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -3,8 +3,10 @@ package chiselTests import chisel3._ -import chisel3.stage.ChiselStage import chisel3.experimental.DataMirror +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage, NoRunFirrtlCompilerAnnotation} +import firrtl.annotations.NoTargetAnnotation +import firrtl.options.Unserializable class SimpleIO extends Bundle { val in = Input(UInt(32.W)) @@ -140,6 +142,17 @@ class ModuleSpec extends ChiselPropSpec with Utils { assert(checkModule(this)) }) } + + property("object chisel3.util.experimental.getAnnotations should return current annotations.") { + case class DummyAnnotation() extends NoTargetAnnotation with Unserializable + (new ChiselStage).transform(Seq( + ChiselGeneratorAnnotation(() => new RawModule { + assert(chisel3.util.experimental.getAnnotations().contains(DummyAnnotation())) + }), + DummyAnnotation(), + NoRunFirrtlCompilerAnnotation)) + } + property("DataMirror.modulePorts should work") { ChiselStage.elaborate(new Module { val io = IO(new Bundle { }) |
