summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchuyler Eldridge2019-08-15 19:52:36 -0400
committerGitHub2019-08-15 19:52:36 -0400
commit8407cbafe37406301fe7437a7a0cb8bf283ada09 (patch)
tree80262cf5cb17b8f0b4b044925bb9b6d19823263f /src
parent24dddea6dccea5a570cece78324a5db624c7303a (diff)
parente254fabacb003549038f38f8209b66bf65a7f789 (diff)
Merge pull request #1155 from freechipsproject/dependency-api
Dependency API (take 2)
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/chisel3/Driver.scala38
-rw-r--r--src/main/scala/chisel3/stage/ChiselStage.scala29
-rw-r--r--src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala6
-rw-r--r--src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala6
-rw-r--r--src/main/scala/chisel3/stage/phases/Checks.scala6
-rw-r--r--src/main/scala/chisel3/stage/phases/Convert.scala6
-rw-r--r--src/main/scala/chisel3/stage/phases/DriverCompatibility.scala55
-rw-r--r--src/main/scala/chisel3/stage/phases/Elaborate.scala4
-rw-r--r--src/main/scala/chisel3/stage/phases/Emitter.scala11
-rw-r--r--src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala6
-rw-r--r--src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala6
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 }