diff options
| author | Schuyler Eldridge | 2019-08-15 19:52:36 -0400 |
|---|---|---|
| committer | GitHub | 2019-08-15 19:52:36 -0400 |
| commit | 8407cbafe37406301fe7437a7a0cb8bf283ada09 (patch) | |
| tree | 80262cf5cb17b8f0b4b044925bb9b6d19823263f /src | |
| parent | 24dddea6dccea5a570cece78324a5db624c7303a (diff) | |
| parent | e254fabacb003549038f38f8209b66bf65a7f789 (diff) | |
Merge pull request #1155 from freechipsproject/dependency-api
Dependency API (take 2)
Diffstat (limited to 'src')
11 files changed, 122 insertions, 51 deletions
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 66146755..a78cc92f 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -6,7 +6,8 @@ import chisel3.internal.ErrorLog import chisel3.experimental.RawModule import internal.firrtl._ import firrtl._ -import firrtl.options.Phase +import firrtl.options.{Phase, PhaseManager} +import firrtl.options.phases.DeletedWrapper import firrtl.options.Viewer.view import firrtl.annotations.JsonProtocol import firrtl.util.{BackendCompilationUtilities => FirrtlBackendCompilationUtilities} @@ -200,22 +201,27 @@ object Driver extends BackendCompilationUtilities { optionsManager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions, dut: () => RawModule): ChiselExecutionResult = { - val annos = ChiselGeneratorAnnotation(dut) +: - (optionsManager.chiselOptions.toAnnotations ++ - optionsManager.firrtlOptions.toAnnotations ++ - optionsManager.commonOptions.toAnnotations) + val annos: AnnotationSeq = + Seq(DriverCompatibility.OptionsManagerAnnotation(optionsManager), ChiselGeneratorAnnotation(dut)) ++ + optionsManager.chiselOptions.toAnnotations ++ + optionsManager.firrtlOptions.toAnnotations ++ + optionsManager.commonOptions.toAnnotations - val phases: Seq[Phase] = - Seq( new DriverCompatibility.AddImplicitOutputFile, - new DriverCompatibility.AddImplicitOutputAnnotationFile, - new DriverCompatibility.DisableFirrtlStage, - new ChiselStage, - new DriverCompatibility.MutateOptionsManager(optionsManager), - new DriverCompatibility.ReEnableFirrtlStage, - new firrtl.stage.phases.DriverCompatibility.AddImplicitOutputFile, - new firrtl.stage.phases.DriverCompatibility.AddImplicitEmitter, - new chisel3.stage.phases.MaybeFirrtlStage ) - .map(firrtl.options.phases.DeletedWrapper(_)) + val targets = + Seq( classOf[DriverCompatibility.AddImplicitOutputFile], + classOf[DriverCompatibility.AddImplicitOutputAnnotationFile], + classOf[DriverCompatibility.DisableFirrtlStage], + classOf[ChiselStage], + classOf[DriverCompatibility.MutateOptionsManager], + classOf[DriverCompatibility.ReEnableFirrtlStage], + classOf[DriverCompatibility.FirrtlPreprocessing], + classOf[chisel3.stage.phases.MaybeFirrtlStage] ) + val currentState = + Seq( classOf[firrtl.stage.phases.DriverCompatibility.AddImplicitFirrtlFile] ) + + val phases: Seq[Phase] = new PhaseManager(targets, currentState) { + override val wrappers = Seq( DeletedWrapper(_: Phase) ) + }.transformOrder val annosx = try { phases.foldLeft(annos)( (a, p) => p.transform(a) ) diff --git a/src/main/scala/chisel3/stage/ChiselStage.scala b/src/main/scala/chisel3/stage/ChiselStage.scala index 0c6512af..923867d7 100644 --- a/src/main/scala/chisel3/stage/ChiselStage.scala +++ b/src/main/scala/chisel3/stage/ChiselStage.scala @@ -3,25 +3,28 @@ package chisel3.stage import firrtl.AnnotationSeq -import firrtl.options.{Phase, Shell, Stage} +import firrtl.options.{Phase, PhaseManager, PreservesAll, Shell, Stage} +import firrtl.options.phases.DeletedWrapper import firrtl.stage.FirrtlCli -class ChiselStage extends Stage { +class ChiselStage extends Stage with PreservesAll[Phase] { val shell: Shell = new Shell("chisel") with ChiselCli with FirrtlCli - private val phases: Seq[Phase] = - Seq( new chisel3.stage.phases.Checks, - new chisel3.stage.phases.Elaborate, - new chisel3.stage.phases.AddImplicitOutputFile, - new chisel3.stage.phases.AddImplicitOutputAnnotationFile, - new chisel3.stage.phases.MaybeAspectPhase, - new chisel3.stage.phases.Emitter, - new chisel3.stage.phases.Convert, - new chisel3.stage.phases.MaybeFirrtlStage ) - .map(firrtl.options.phases.DeletedWrapper(_)) + private val targets = + Seq( classOf[chisel3.stage.phases.Checks], + classOf[chisel3.stage.phases.Elaborate], + classOf[chisel3.stage.phases.AddImplicitOutputFile], + classOf[chisel3.stage.phases.AddImplicitOutputAnnotationFile], + classOf[chisel3.stage.phases.MaybeAspectPhase], + classOf[chisel3.stage.phases.Emitter], + classOf[chisel3.stage.phases.Convert], + classOf[chisel3.stage.phases.MaybeFirrtlStage] ) def run(annotations: AnnotationSeq): AnnotationSeq = /* @todo: Should this be wrapped in a try/catch? */ - phases.foldLeft(annotations)( (a, f) => f.transform(a) ) + new PhaseManager(targets) { override val wrappers = Seq( (a: Phase) => DeletedWrapper(a) ) } + .transformOrder + .map(firrtl.options.phases.DeletedWrapper(_)) + .foldLeft(annotations)( (a, f) => f.transform(a) ) } diff --git a/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala b/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala index de251ab6..c7761d24 100644 --- a/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala +++ b/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala @@ -4,12 +4,14 @@ package chisel3.stage.phases import chisel3.stage.ChiselCircuitAnnotation import firrtl.AnnotationSeq -import firrtl.options.{OutputAnnotationFileAnnotation, Phase} +import firrtl.options.{OutputAnnotationFileAnnotation, Phase, PreservesAll} /** Adds an [[firrtl.options.OutputAnnotationFileAnnotation]] if one does not exist. This replicates old behavior where * an output annotation file was always written. */ -class AddImplicitOutputAnnotationFile extends Phase { +class AddImplicitOutputAnnotationFile extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[Elaborate]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations .collectFirst{ case _: OutputAnnotationFileAnnotation => annotations } diff --git a/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala b/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala index 4a4dac72..cf808d26 100644 --- a/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala +++ b/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala @@ -3,14 +3,16 @@ package chisel3.stage.phases import firrtl.AnnotationSeq -import firrtl.options.Phase +import firrtl.options.{Phase, PreservesAll} import chisel3.stage.{ChiselCircuitAnnotation, ChiselOutputFileAnnotation} /** Add a output file for a Chisel circuit, derived from the top module in the circuit, if no * [[ChiselOutputFileAnnotation]] already exists. */ -class AddImplicitOutputFile extends Phase { +class AddImplicitOutputFile extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[Elaborate]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.collectFirst{ case _: ChiselOutputFileAnnotation => annotations }.getOrElse{ diff --git a/src/main/scala/chisel3/stage/phases/Checks.scala b/src/main/scala/chisel3/stage/phases/Checks.scala index e2606019..879379ce 100644 --- a/src/main/scala/chisel3/stage/phases/Checks.scala +++ b/src/main/scala/chisel3/stage/phases/Checks.scala @@ -6,12 +6,14 @@ import chisel3.stage.{ChiselOutputFileAnnotation, NoRunFirrtlCompilerAnnotation, import firrtl.AnnotationSeq import firrtl.annotations.Annotation -import firrtl.options.{OptionsException, Phase} +import firrtl.options.{OptionsException, Phase, PreservesAll} /** Sanity checks an [[firrtl.AnnotationSeq]] before running the main [[firrtl.options.Phase]]s of * [[chisel3.stage.ChiselStage]]. */ -class Checks extends Phase { +class Checks extends Phase with PreservesAll[Phase] { + + override val dependents = Seq(classOf[Elaborate]) def transform(annotations: AnnotationSeq): AnnotationSeq = { val noF, st, outF = collection.mutable.ListBuffer[Annotation]() diff --git a/src/main/scala/chisel3/stage/phases/Convert.scala b/src/main/scala/chisel3/stage/phases/Convert.scala index f08367c6..ac477330 100644 --- a/src/main/scala/chisel3/stage/phases/Convert.scala +++ b/src/main/scala/chisel3/stage/phases/Convert.scala @@ -6,7 +6,7 @@ import chisel3.experimental.RunFirrtlTransform import chisel3.internal.firrtl.Converter import chisel3.stage.ChiselCircuitAnnotation import firrtl.{AnnotationSeq, Transform} -import firrtl.options.Phase +import firrtl.options.{Phase, PreservesAll} import firrtl.stage.{FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation} /** This prepares a [[ChiselCircuitAnnotation]] for compilation with FIRRTL. This does three things: @@ -14,7 +14,9 @@ import firrtl.stage.{FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation} * - Extracts all [[firrtl.annotations.Annotation]]s from the [[chisel3.internal.firrtl.Circuit]] * - Generates any needed [[RunFirrtlTransformAnnotation]]s from extracted [[firrtl.annotations.Annotation]]s */ -class Convert extends Phase { +class Convert extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[Elaborate]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap { case a: ChiselCircuitAnnotation => diff --git a/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala b/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala index b7674aa1..11264ece 100644 --- a/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala +++ b/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala @@ -4,12 +4,12 @@ package chisel3.stage.phases import firrtl.{AnnotationSeq, ExecutionOptionsManager, HasFirrtlOptions} import firrtl.annotations.NoTargetAnnotation -import firrtl.options.{OutputAnnotationFileAnnotation, Phase} +import firrtl.options.{OptionsException, OutputAnnotationFileAnnotation, Phase, PreservesAll, Unserializable} import firrtl.stage.{FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation} import firrtl.stage.phases.DriverCompatibility.TopNameAnnotation import chisel3.HasChiselExecutionOptions -import chisel3.stage.{NoRunFirrtlCompilerAnnotation, ChiselOutputFileAnnotation} +import chisel3.stage.{ChiselStage, NoRunFirrtlCompilerAnnotation, ChiselOutputFileAnnotation} /** This provides components of a compatibility wrapper around Chisel's deprecated [[chisel3.Driver]]. * @@ -25,7 +25,9 @@ object DriverCompatibility { * the correct behavior before a circuit has been elaborated. * @note the output suffix is unspecified and will be set by the underlying [[firrtl.EmittedComponent]] */ - private[chisel3] class AddImplicitOutputFile extends Phase { + private [chisel3] class AddImplicitOutputFile extends Phase with PreservesAll[Phase] { + + override val dependents = Seq(classOf[chisel3.stage.ChiselStage]) def transform(annotations: AnnotationSeq): AnnotationSeq = { val hasOutputFile = annotations @@ -47,7 +49,9 @@ object DriverCompatibility { * correct behavior before a circuit has been elaborated. * @note the output suffix is unspecified and will be set by [[firrtl.options.phases.WriteOutputAnnotations]] */ - private[chisel3] class AddImplicitOutputAnnotationFile extends Phase { + private[chisel3] class AddImplicitOutputAnnotationFile extends Phase with PreservesAll[Phase] { + + override val dependents = Seq(classOf[chisel3.stage.ChiselStage]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations @@ -69,14 +73,18 @@ object DriverCompatibility { * situations where you need to do something between Chisel compilation and FIRRTL compilations, e.g., update a * mutable data structure. */ - private[chisel3] class DisableFirrtlStage extends Phase { + private[chisel3] class DisableFirrtlStage extends Phase with PreservesAll[Phase] { + + override val dependents = Seq(classOf[ChiselStage]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations .collectFirst { case NoRunFirrtlCompilerAnnotation => annotations } .getOrElse { Seq(RunFirrtlCompilerAnnotation, NoRunFirrtlCompilerAnnotation) ++ annotations } } - private[chisel3] class ReEnableFirrtlStage extends Phase { + private[chisel3] class ReEnableFirrtlStage extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[DisableFirrtlStage], classOf[ChiselStage]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations .collectFirst { case RunFirrtlCompilerAnnotation => @@ -90,15 +98,27 @@ object DriverCompatibility { } + private[chisel3] case class OptionsManagerAnnotation( + manager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions) + extends NoTargetAnnotation with Unserializable + /** Mutate an input [[firrtl.ExecutionOptionsManager]] based on information encoded in an [[firrtl.AnnotationSeq]]. * This is intended to be run between [[chisel3.stage.ChiselStage ChiselStage]] and [[firrtl.stage.FirrtlStage]] if * you want to have backwards compatibility with an [[firrtl.ExecutionOptionsManager]]. */ - private[chisel3] class MutateOptionsManager( - optionsManager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions) extends Phase { + private[chisel3] class MutateOptionsManager extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[chisel3.stage.ChiselStage]) + + override val dependents = Seq(classOf[ReEnableFirrtlStage]) def transform(annotations: AnnotationSeq): AnnotationSeq = { + val optionsManager = annotations + .collectFirst{ case OptionsManagerAnnotation(a) => a } + .getOrElse{ throw new OptionsException( + "An OptionsManagerException must exist for Chisel Driver compatibility mode") } + val firrtlCircuit = annotations.collectFirst{ case FirrtlCircuitAnnotation(a) => a } optionsManager.firrtlOptions = optionsManager.firrtlOptions.copy( firrtlCircuit = firrtlCircuit, @@ -112,4 +132,23 @@ object DriverCompatibility { } + /** A [[Phase]] that lets us run + * @todo a better solution than the current state hack below may be needed + */ + private [chisel3] class FirrtlPreprocessing extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[ChiselStage], classOf[MutateOptionsManager], classOf[ReEnableFirrtlStage]) + + override val dependents = Seq(classOf[MaybeFirrtlStage]) + + private val phases = + Seq( new firrtl.stage.phases.DriverCompatibility.AddImplicitOutputFile, + new firrtl.stage.phases.DriverCompatibility.AddImplicitEmitter ) + + override def transform(annotations: AnnotationSeq): AnnotationSeq = + phases + .foldLeft(annotations)( (a, p) => p.transform(a) ) + + } + } diff --git a/src/main/scala/chisel3/stage/phases/Elaborate.scala b/src/main/scala/chisel3/stage/phases/Elaborate.scala index 2ec5f92c..150eacbe 100644 --- a/src/main/scala/chisel3/stage/phases/Elaborate.scala +++ b/src/main/scala/chisel3/stage/phases/Elaborate.scala @@ -9,11 +9,11 @@ import chisel3.internal.ErrorLog import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOptions} import firrtl.AnnotationSeq import firrtl.options.Viewer.view -import firrtl.options.{OptionsException, Phase} +import firrtl.options.{OptionsException, Phase, PreservesAll} /** Elaborate all [[chisel3.stage.ChiselGeneratorAnnotation]]s into [[chisel3.stage.ChiselCircuitAnnotation]]s. */ -class Elaborate extends Phase { +class Elaborate extends Phase with PreservesAll[Phase] { /** * @todo Change this to print to STDERR (`Console.err.println`) diff --git a/src/main/scala/chisel3/stage/phases/Emitter.scala b/src/main/scala/chisel3/stage/phases/Emitter.scala index 1bdb9f8d..a0530bd2 100644 --- a/src/main/scala/chisel3/stage/phases/Emitter.scala +++ b/src/main/scala/chisel3/stage/phases/Emitter.scala @@ -24,6 +24,17 @@ import java.io.{File, FileWriter} */ class Emitter extends Phase { + override val prerequisites = + Seq( classOf[Elaborate], + classOf[AddImplicitOutputFile], + classOf[AddImplicitOutputAnnotationFile], + classOf[MaybeAspectPhase] ) + + override def invalidates(phase: Phase): Boolean = phase match { + case _: Elaborate => true + case _ => false + } + def transform(annotations: AnnotationSeq): AnnotationSeq = { val copts = view[ChiselOptions](annotations) val sopts = view[StageOptions](annotations) diff --git a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala index 3e8b8feb..a69bc352 100644 --- a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala +++ b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala @@ -4,11 +4,13 @@ package chisel3.stage.phases import chisel3.aop.Aspect import firrtl.AnnotationSeq -import firrtl.options.Phase +import firrtl.options.{Phase, PreservesAll} /** Run [[AspectPhase]] if a [[chisel3.aop.Aspect]] is present. */ -class MaybeAspectPhase extends Phase { +class MaybeAspectPhase extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[Elaborate]) def transform(annotations: AnnotationSeq): AnnotationSeq = { if(annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) { diff --git a/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala b/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala index f830c182..838b6819 100644 --- a/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala +++ b/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala @@ -5,12 +5,14 @@ package chisel3.stage.phases import chisel3.stage.NoRunFirrtlCompilerAnnotation import firrtl.AnnotationSeq -import firrtl.options.Phase +import firrtl.options.{Phase, PreservesAll} import firrtl.stage.FirrtlStage /** Run [[firrtl.stage.FirrtlStage]] if a [[chisel3.stage.NoRunFirrtlCompilerAnnotation]] is not present. */ -class MaybeFirrtlStage extends Phase { +class MaybeFirrtlStage extends Phase with PreservesAll[Phase] { + + override val prerequisites = Seq(classOf[Convert]) def transform(annotations: AnnotationSeq): AnnotationSeq = annotations .collectFirst { case NoRunFirrtlCompilerAnnotation => annotations } |
