-
Notifications
You must be signed in to change notification settings - Fork 615
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1004 from freechipsproject/chisel-stage
Chisel stage
- Loading branch information
Showing
25 changed files
with
1,110 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3.stage | ||
|
||
import firrtl.annotations.{Annotation, NoTargetAnnotation} | ||
import firrtl.options.{HasShellOptions, OptionsException, ShellOption, Unserializable} | ||
|
||
import chisel3.{ChiselException, Module} | ||
import chisel3.experimental.RawModule | ||
import chisel3.internal.Builder | ||
import chisel3.internal.firrtl.Circuit | ||
|
||
/** Mixin that indicates that this is an [[firrtl.annotations.Annotation]] used to generate a [[ChiselOptions]] view. | ||
*/ | ||
sealed trait ChiselOption extends Unserializable { this: Annotation => } | ||
|
||
/** Disable the execution of the FIRRTL compiler by Chisel | ||
*/ | ||
case object NoRunFirrtlCompilerAnnotation extends NoTargetAnnotation with ChiselOption with HasShellOptions { | ||
|
||
val options = Seq( | ||
new ShellOption[Unit]( | ||
longOption = "no-run-firrtl", | ||
toAnnotationSeq = _ => Seq(NoRunFirrtlCompilerAnnotation), | ||
helpText = "Do not run the FIRRTL compiler (generate FIRRTL IR from Chisel and exit)", | ||
shortOption = Some("chnrf") ) ) | ||
|
||
} | ||
|
||
/** On an exception, this will cause the full stack trace to be printed as opposed to a pruned stack trace. | ||
*/ | ||
case object PrintFullStackTraceAnnotation extends NoTargetAnnotation with ChiselOption with HasShellOptions { | ||
|
||
val options = Seq( | ||
new ShellOption[Unit]( | ||
longOption = "full-stacktrace", | ||
toAnnotationSeq = _ => Seq(PrintFullStackTraceAnnotation), | ||
helpText = "Show full stack trace when an exception is thrown" ) ) | ||
|
||
} | ||
|
||
/** An [[firrtl.annotations.Annotation]] storing a function that returns a Chisel module | ||
* @param gen a generator function | ||
*/ | ||
case class ChiselGeneratorAnnotation(gen: () => RawModule) extends NoTargetAnnotation with Unserializable { | ||
|
||
/** Run elaboration on the Chisel module generator function stored by this [[firrtl.annotations.Annotation]] | ||
*/ | ||
def elaborate: ChiselCircuitAnnotation = try { | ||
ChiselCircuitAnnotation(Builder.build(Module(gen()))) | ||
} catch { | ||
case e @ (_: OptionsException | _: ChiselException) => throw e | ||
case e: Throwable => | ||
throw new OptionsException(s"Exception thrown when elaborating ChiselGeneratorAnnotation", e) | ||
} | ||
|
||
} | ||
|
||
object ChiselGeneratorAnnotation extends HasShellOptions { | ||
|
||
/** Construct a [[ChiselGeneratorAnnotation]] with a generator function that will try to construct a Chisel Module | ||
* from using that Module's name. The Module must both exist in the class path and not take parameters. | ||
* @param name a module name | ||
* @throws firrtl.options.OptionsException if the module name is not found or if no parameterless constructor for | ||
* that Module is found | ||
*/ | ||
def apply(name: String): ChiselGeneratorAnnotation = { | ||
val gen = () => try { | ||
Class.forName(name).asInstanceOf[Class[_ <: RawModule]].newInstance() | ||
} catch { | ||
case e: ClassNotFoundException => | ||
throw new OptionsException(s"Unable to locate module '$name'! (Did you misspell it?)", e) | ||
case e: InstantiationException => | ||
throw new OptionsException( | ||
s"Unable to create instance of module '$name'! (Does this class take parameters?)", e) | ||
} | ||
ChiselGeneratorAnnotation(gen) | ||
} | ||
|
||
val options = Seq( | ||
new ShellOption[String]( | ||
longOption = "module", | ||
toAnnotationSeq = (a: String) => Seq(ChiselGeneratorAnnotation(a)), | ||
helpText = "The name of a Chisel module to elaborate (module must be in the classpath)", | ||
helpValueName = Some("<package>.<module>") ) ) | ||
|
||
} | ||
|
||
/** Stores a Chisel Circuit | ||
* @param circuit a Chisel Circuit | ||
*/ | ||
case class ChiselCircuitAnnotation(circuit: Circuit) extends NoTargetAnnotation with ChiselOption | ||
|
||
case class ChiselOutputFileAnnotation(file: String) extends NoTargetAnnotation with ChiselOption | ||
|
||
object ChiselOutputFileAnnotation extends HasShellOptions { | ||
|
||
val options = Seq( | ||
new ShellOption[String]( | ||
longOption = "chisel-output-file", | ||
toAnnotationSeq = (a: String) => Seq(ChiselOutputFileAnnotation(a)), | ||
helpText = "Write Chisel-generated FIRRTL to this file (default: <circuit-main>.fir)", | ||
helpValueName = Some("<file>") ) ) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3.stage | ||
|
||
import firrtl.options.Shell | ||
|
||
trait ChiselCli { this: Shell => | ||
parser.note("Chisel Front End Options") | ||
Seq( NoRunFirrtlCompilerAnnotation, | ||
PrintFullStackTraceAnnotation ) | ||
.foreach(_.addOptions(parser)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3.stage | ||
|
||
import chisel3.internal.firrtl.Circuit | ||
|
||
class ChiselOptions private[stage] ( | ||
val runFirrtlCompiler: Boolean = true, | ||
val printFullStackTrace: Boolean = false, | ||
val outputFile: Option[String] = None, | ||
val chiselCircuit: Option[Circuit] = None) { | ||
|
||
private[stage] def copy( | ||
runFirrtlCompiler: Boolean = runFirrtlCompiler, | ||
printFullStackTrace: Boolean = printFullStackTrace, | ||
outputFile: Option[String] = outputFile, | ||
chiselCircuit: Option[Circuit] = chiselCircuit ): ChiselOptions = { | ||
|
||
new ChiselOptions( | ||
runFirrtlCompiler = runFirrtlCompiler, | ||
printFullStackTrace = printFullStackTrace, | ||
outputFile = outputFile, | ||
chiselCircuit = chiselCircuit ) | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3.stage | ||
|
||
import firrtl.AnnotationSeq | ||
import firrtl.options.{Phase, Shell, Stage} | ||
import firrtl.stage.FirrtlCli | ||
|
||
class ChiselStage extends Stage { | ||
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.Emitter, | ||
new chisel3.stage.phases.Convert, | ||
new chisel3.stage.phases.MaybeFirrtlStage ) | ||
.map(firrtl.options.phases.DeletedWrapper(_)) | ||
|
||
def run(annotations: AnnotationSeq): AnnotationSeq = | ||
/* @todo: Should this be wrapped in a try/catch? */ | ||
phases.foldLeft(annotations)( (a, f) => f.transform(a) ) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3 | ||
|
||
import firrtl._ | ||
import firrtl.annotations.DeletedAnnotation | ||
import firrtl.options.OptionsView | ||
|
||
import chisel3.internal.firrtl.{Circuit => ChiselCircuit} | ||
import chisel3.stage.phases.{Convert, Emitter} | ||
|
||
package object stage { | ||
|
||
implicit object ChiselOptionsView extends OptionsView[ChiselOptions] { | ||
|
||
def view(options: AnnotationSeq): ChiselOptions = options | ||
.collect { case a: ChiselOption => a } | ||
.foldLeft(new ChiselOptions()){ (c, x) => | ||
x match { | ||
case _: NoRunFirrtlCompilerAnnotation.type => c.copy(runFirrtlCompiler = false) | ||
case _: PrintFullStackTraceAnnotation.type => c.copy(printFullStackTrace = true) | ||
case ChiselOutputFileAnnotation(f) => c.copy(outputFile = Some(f)) | ||
case ChiselCircuitAnnotation(a) => c.copy(chiselCircuit = Some(a)) | ||
} | ||
} | ||
|
||
} | ||
|
||
private[chisel3] implicit object ChiselExecutionResultView extends OptionsView[ChiselExecutionResult] { | ||
|
||
lazy val dummyWriteEmitted = new firrtl.stage.phases.WriteEmitted | ||
lazy val dummyConvert = new Convert | ||
lazy val dummyEmitter = new Emitter | ||
|
||
def view(options: AnnotationSeq): ChiselExecutionResult = { | ||
var chiselCircuit: Option[ChiselCircuit] = None | ||
var chirrtlCircuit: Option[String] = None | ||
|
||
options.foreach { | ||
case DeletedAnnotation(dummyConvert.name, ChiselCircuitAnnotation(a)) => chiselCircuit = Some(a) | ||
case DeletedAnnotation(dummyEmitter.name, EmittedFirrtlCircuitAnnotation(EmittedFirrtlCircuit(_, a, _))) => | ||
chirrtlCircuit = Some(a) | ||
case _ => | ||
} | ||
|
||
val fResult = firrtl.stage.phases.DriverCompatibility.firrtlResultView(options) | ||
|
||
(chiselCircuit, chirrtlCircuit) match { | ||
case (None, _) => ChiselExecutionFailure("Failed to elaborate Chisel circuit") | ||
case (Some(_), None) => ChiselExecutionFailure("Failed to convert Chisel circuit to FIRRTL") | ||
case (Some(a), Some(b)) => ChiselExecutionSuccess( Some(a), b, Some(fResult)) | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3.stage.phases | ||
|
||
import chisel3.stage.ChiselCircuitAnnotation | ||
import firrtl.AnnotationSeq | ||
import firrtl.options.{OutputAnnotationFileAnnotation, Phase} | ||
|
||
/** 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 { | ||
|
||
def transform(annotations: AnnotationSeq): AnnotationSeq = annotations | ||
.collectFirst{ case _: OutputAnnotationFileAnnotation => annotations } | ||
.getOrElse{ | ||
|
||
val x: Option[AnnotationSeq] = annotations | ||
.collectFirst{ case a: ChiselCircuitAnnotation => | ||
OutputAnnotationFileAnnotation(a.circuit.name) +: annotations } | ||
|
||
x.getOrElse(annotations) | ||
} | ||
|
||
} |
Oops, something went wrong.