diff options
| author | Schuyler Eldridge | 2019-01-14 21:01:29 -0500 |
|---|---|---|
| committer | Schuyler Eldridge | 2019-05-22 16:19:13 -0400 |
| commit | 23641521174ba828feb32dc1c65c13a3d6b46970 (patch) | |
| tree | 22fe46c8f675ca3739f893890efc2479f367d9a1 /src/main | |
| parent | 07ea0bac73d2ee5c9d09e9f3c07275340f0e75bb (diff) | |
Make Driver a ChiselStage compatibility layer
This converts the original chisel3.Driver to use
chisel3.stage.ChiselStage. This is implemented in the following way:
1. ExecutionOptions are converted to an AnnotationSeq
2. The AnnotationSeq is preprocessed using phases contained in the
Chisel DriverCompatibility objects. One of these *disables* the
execution of FirrtlStage by ChiselStage.
3. ChiselStage runs on the preprocessed AnnotationSeq
4. The input ExecutionOptionsManager is mutated based on the output
of ChiselStage.
5. The FIRRTL stage is re-enabled if it's supposed to run and
selected FIRRTL DriverCompatibility phases run.
6. FirrtlStage runs
7. The output AnnotationSeq is "viewed" as a ChiselExecutionResult
This modifies the original DriverSpec to make it more verbose with the
addition of info statements. The functionality of the DriverSpec is
unmodified.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/chisel3/Driver.scala | 80 |
1 files changed, 26 insertions, 54 deletions
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 303f4599..906ae7fc 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -5,11 +5,15 @@ package chisel3 import chisel3.internal.ErrorLog import chisel3.internal.firrtl._ import chisel3.experimental.{RawModule, RunFirrtlTransform} +import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselStage, ChiselExecutionResultView} +import chisel3.stage.phases.DriverCompatibility import java.io._ import firrtl._ import firrtl.annotations.JsonProtocol +import firrtl.options.Phase +import firrtl.options.Viewer.view import firrtl.util.{BackendCompilationUtilities => FirrtlBackendCompilationUtilities} /** @@ -196,8 +200,26 @@ object Driver extends BackendCompilationUtilities { def execute( // scalastyle:ignore method.length optionsManager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions, dut: () => RawModule): ChiselExecutionResult = { - val circuitOpt = try { - Some(elaborate(dut)) + + val annos = 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 annosx = try { + phases.foldLeft(annos)( (a, p) => p.transform(a) ) } catch { case ce: ChiselException => val stackTrace = if (!optionsManager.chiselOptions.printFullStackTrace) { @@ -208,60 +230,10 @@ object Driver extends BackendCompilationUtilities { sw.toString } Predef.augmentString(stackTrace).lines.foreach(line => println(s"${ErrorLog.errTag} $line")) // scalastyle:ignore regex line.size.limit - None + annos } - circuitOpt.map { circuit => - // this little hack let's us set the topName with the circuit name if it has not been set from args - optionsManager.setTopNameIfNotSet(circuit.name) - - val firrtlOptions = optionsManager.firrtlOptions - val chiselOptions = optionsManager.chiselOptions - - val firrtlCircuit = Converter.convert(circuit) - - // Still emit to leave an artifact (and because this always has been the behavior) - val firrtlString = Driver.emit(circuit) - val firrtlFileName = firrtlOptions.getInputFileName(optionsManager) - val firrtlFile = new File(firrtlFileName) - - val w = new FileWriter(firrtlFile) - w.write(firrtlString) - w.close() - - // Emit the annotations because it has always been the behavior - val annotationFile = new File(optionsManager.getBuildFileName("anno.json")) - val af = new FileWriter(annotationFile) - val firrtlAnnos = circuit.annotations.map(_.toFirrtl) - af.write(JsonProtocol.serialize(firrtlAnnos)) - af.close() - - /** Find the set of transform classes associated with annotations then - * instantiate an instance of each transform - * @note Annotations targeting firrtl.Transform will not result in any - * transform being instantiated - */ - val transforms = circuit.annotations - .collect { case anno: RunFirrtlTransform => anno.transformClass } - .distinct - .filterNot(_ == classOf[firrtl.Transform]) - .map { transformClass: Class[_ <: Transform] => - transformClass.newInstance() - } - /* This passes the firrtl source and annotations directly to firrtl */ - optionsManager.firrtlOptions = optionsManager.firrtlOptions.copy( - firrtlCircuit = Some(firrtlCircuit), - annotations = optionsManager.firrtlOptions.annotations ++ firrtlAnnos, - customTransforms = optionsManager.firrtlOptions.customTransforms ++ transforms.toList) - - val firrtlExecutionResult = if(chiselOptions.runFirrtlCompiler) { - Some(firrtl.Driver.execute(optionsManager)) - } - else { - None - } - ChiselExecutionSuccess(Some(circuit), firrtlString, firrtlExecutionResult) - }.getOrElse(ChiselExecutionFailure("could not elaborate circuit")) + view[ChiselExecutionResult](annosx) } /** |
