diff options
| author | Jack Koenig | 2017-03-06 14:51:20 -0600 |
|---|---|---|
| committer | GitHub | 2017-03-06 14:51:20 -0600 |
| commit | 3d58123ae654a2101ba81304ca3863b3be12c4f3 (patch) | |
| tree | 2e662485fef5327a2697dbd4a9b42a2cdc5bae5f /src/main/scala/firrtl/ExecutionOptionsManager.scala | |
| parent | c89f74f19dd5162ee533a0a20825819bc52bc73e (diff) | |
Add ability to emit 1 file per module (#443)
Changes Emitters to also be Transforms and use Annotations for both
telling an emitter to do emission as well as getting the emitted result.
Helper functions ease the use of the new interface. Also adds a
FirrtlExecutionOptions field as well as a command-line option. Use of
Writers in Compilers and Emitters is now deprecated.
Diffstat (limited to 'src/main/scala/firrtl/ExecutionOptionsManager.scala')
| -rw-r--r-- | src/main/scala/firrtl/ExecutionOptionsManager.scala | 82 |
1 files changed, 70 insertions, 12 deletions
diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala index 5615da99..2d221e6b 100644 --- a/src/main/scala/firrtl/ExecutionOptionsManager.scala +++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala @@ -125,6 +125,15 @@ trait HasCommonOptions { parser.help("help").text("prints this usage text") } +/** Firrtl output configuration specified by [[FirrtlExecutionOptions]] + * + * Derived from the fields of the execution options + * @see [[FirrtlExecutionOptions.getOutputConfig]] + */ +sealed abstract class OutputConfig +final case class SingleFile(targetFile: String) extends OutputConfig +final case class OneFilePerModule(targetDir: String) extends OutputConfig + /** * The options that firrtl supports in callable component sense * @@ -133,7 +142,6 @@ trait HasCommonOptions { * @param compilerName which compiler to use * @param annotations annotations to pass to compiler */ - case class FirrtlExecutionOptions( inputFileNameOverride: String = "", outputFileNameOverride: String = "", @@ -144,9 +152,13 @@ case class FirrtlExecutionOptions( customTransforms: Seq[Transform] = List.empty, annotations: List[Annotation] = List.empty, annotationFileNameOverride: String = "", - forceAppendAnnoFile: Boolean = false) + forceAppendAnnoFile: Boolean = false, + emitOneFilePerModule: Boolean = false) extends ComposableOptions { + require(!(emitOneFilePerModule && outputFileNameOverride.nonEmpty), + "Cannot both specify the output filename and emit one file per module!!!") + def infoMode: InfoMode = { infoModeName match { case "use" => UseInfo @@ -186,14 +198,43 @@ case class FirrtlExecutionOptions( def getInputFileName(optionsManager: ExecutionOptionsManager): String = { optionsManager.getBuildFileName("fir", inputFileNameOverride) } - /** - * build the output file name, taking overriding parameters + /** Get the user-specified [[OutputConfig]] * * @param optionsManager this is needed to access build function and its common options - * @return + * @return the output configuration + */ + def getOutputConfig(optionsManager: ExecutionOptionsManager): OutputConfig = { + if (emitOneFilePerModule) OneFilePerModule(optionsManager.targetDirName) + else SingleFile(optionsManager.getBuildFileName(outputSuffix, outputFileNameOverride)) + } + /** Get the user-specified targetFile assuming [[OutputConfig]] is [[SingleFile]] + * + * @param optionsManager this is needed to access build function and its common options + * @return the targetFile as a String */ - def getOutputFileName(optionsManager: ExecutionOptionsManager): String = { - optionsManager.getBuildFileName(outputSuffix, outputFileNameOverride) + def getTargetFile(optionsManager: ExecutionOptionsManager): String = { + getOutputConfig(optionsManager) match { + case SingleFile(targetFile) => targetFile + case other => throw new Exception("OutputConfig is not SingleFile!") + } + } + /** Gives annotations based on the output configuration + * + * @param optionsManager this is needed to access build function and its common options + * @return Annotations that will be consumed by emitter Transforms + */ + def getEmitterAnnos(optionsManager: ExecutionOptionsManager): Seq[Annotation] = { + // TODO should this be a public function? + val emitter = compilerName match { + case "high" => classOf[HighFirrtlEmitter] + case "middle" => classOf[MiddleFirrtlEmitter] + case "low" => classOf[LowFirrtlEmitter] + case "verilog" => classOf[VerilogEmitter] + } + getOutputConfig(optionsManager) match { + case SingleFile(_) => Seq(EmitCircuitAnnotation(emitter)) + case OneFilePerModule(_) => Seq(EmitAllModulesAnnotation(emitter)) + } } /** * build the annotation file name, taking overriding parameters @@ -223,8 +264,13 @@ trait HasFirrtlOptions { parser.opt[String]("output-file") .abbr("o") - .valueName ("<output>"). - foreach { x => + .valueName("<output>") + .validate { x => + if (firrtlOptions.emitOneFilePerModule) + parser.failure("Cannot override output-file if split-modules is specified") + else parser.success + } + .foreach { x => firrtlOptions = firrtlOptions.copy(outputFileNameOverride = x) }.text { "use this to override the default output file name, default is empty" @@ -234,7 +280,7 @@ trait HasFirrtlOptions { .abbr("faf") .valueName ("<output>"). foreach { x => - firrtlOptions = firrtlOptions.copy(outputFileNameOverride = x) + firrtlOptions = firrtlOptions.copy(annotationFileNameOverride = x) }.text { "use this to override the default annotation file name, default is empty" } @@ -334,8 +380,20 @@ trait HasFirrtlOptions { "List which signal drives each clock of every descendent of specified module" } - parser.note("") + parser.opt[Unit]("split-modules") + .abbr("fsm") + .validate { x => + if (firrtlOptions.outputFileNameOverride.nonEmpty) + parser.failure("Cannot split-modules if output-file is specified") + else parser.success + } + .foreach { _ => + firrtlOptions = firrtlOptions.copy(emitOneFilePerModule = true) + }.text { + "Emit each module to its own file in the target directory." + } + parser.note("") } sealed trait FirrtlExecutionResult @@ -345,7 +403,7 @@ sealed trait FirrtlExecutionResult * the type of compile * * @param emitType The name of the compiler used, currently "high", "middle", "low", or "verilog" - * @param emitted The text result of the compilation, could be verilog or firrtl text. + * @param emitted The emitted result of compilation */ case class FirrtlExecutionSuccess(emitType: String, emitted: String) extends FirrtlExecutionResult |
