diff options
| author | Jack Koenig | 2018-05-23 11:54:50 -0700 |
|---|---|---|
| committer | GitHub | 2018-05-23 11:54:50 -0700 |
| commit | 87fe48938a3ccc58b1945bae72f0e7305ac14b3b (patch) | |
| tree | 8d809eac737083400ae72b9f11bb2eb3fd91aee1 /src/main | |
| parent | b1709242b5c7b60e21308642947d292545eb2e37 (diff) | |
Add Circuit as option to FirrtlOptions (#814)
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/firrtl/Driver.scala | 78 | ||||
| -rw-r--r-- | src/main/scala/firrtl/ExecutionOptionsManager.scala | 4 |
2 files changed, 53 insertions, 29 deletions
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala index 10489da4..72128274 100644 --- a/src/main/scala/firrtl/Driver.scala +++ b/src/main/scala/firrtl/Driver.scala @@ -148,33 +148,38 @@ object Driver { LegacyAnnotation.convertLegacyAnnos(annos) } - /** - * Run the firrtl compiler using the provided option + // Useful for handling erros in the options + case class OptionsException(msg: String) extends Exception(msg) + + /** Get the Circuit from the compile options * - * @param optionsManager the desired flags to the compiler - * @return a FirrtlExecutionResult indicating success or failure, provide access to emitted data on success - * for downstream tools as desired + * Handles the myriad of ways it can be specified */ - //scalastyle:off cyclomatic.complexity method.length - def execute(optionsManager: ExecutionOptionsManager with HasFirrtlOptions): FirrtlExecutionResult = { - def firrtlConfig = optionsManager.firrtlOptions - - Logger.makeScope(optionsManager) { - val firrtlSource = firrtlConfig.firrtlSource match { - case Some(text) => text.split("\n").toIterator - case None => + def getCircuit(optionsManager: ExecutionOptionsManager with HasFirrtlOptions): Try[ir.Circuit] = { + val firrtlConfig = optionsManager.firrtlOptions + Try { + // Check that only one "override" is used + val circuitSources = Map( + "firrtlSource" -> firrtlConfig.firrtlSource.isDefined, + "firrtlCircuit" -> firrtlConfig.firrtlCircuit.isDefined, + "inputFileNameOverride" -> firrtlConfig.inputFileNameOverride.nonEmpty) + if (circuitSources.values.count(x => x) > 1) { + val msg = circuitSources.collect { case (s, true) => s }.mkString(" and ") + + " are set, only 1 can be set at a time!" + throw new OptionsException(msg) + } + firrtlConfig.firrtlCircuit.getOrElse { + val source = firrtlConfig.firrtlSource.map(_.split("\n").toIterator).getOrElse { if (optionsManager.topName.isEmpty && firrtlConfig.inputFileNameOverride.isEmpty) { val message = "either top-name or input-file-override must be set" - dramaticError(message) - return FirrtlExecutionFailure(message) + throw new OptionsException(message) } if ( optionsManager.topName.isEmpty && firrtlConfig.inputFileNameOverride.nonEmpty && firrtlConfig.outputFileNameOverride.isEmpty) { val message = "inputFileName set but neither top-name or output-file-override is set" - dramaticError(message) - return FirrtlExecutionFailure(message) + throw new OptionsException(message) } val inputFileName = firrtlConfig.getInputFileName(optionsManager) try { @@ -183,26 +188,45 @@ object Driver { catch { case _: FileNotFoundException => val message = s"Input file $inputFileName not found" - dramaticError(message) - return FirrtlExecutionFailure(message) + throw new OptionsException(message) } + } + Parser.parse(source, firrtlConfig.infoMode) } + } + } - var maybeFinalState: Option[CircuitState] = None + /** + * Run the firrtl compiler using the provided option + * + * @param optionsManager the desired flags to the compiler + * @return a FirrtlExecutionResult indicating success or failure, provide access to emitted data on success + * for downstream tools as desired + */ + //scalastyle:off cyclomatic.complexity method.length + def execute(optionsManager: ExecutionOptionsManager with HasFirrtlOptions): FirrtlExecutionResult = { + def firrtlConfig = optionsManager.firrtlOptions + Logger.makeScope(optionsManager) { // Wrap compilation in a try/catch to present Scala MatchErrors in a more user-friendly format. - try { - val annos = getAnnotations(optionsManager) + val finalState = try { + val circuit = getCircuit(optionsManager) match { + case Success(c) => c + case Failure(OptionsException(msg)) => + dramaticError(msg) + return FirrtlExecutionFailure(msg) + case Failure(e) => throw e + } - val parsedInput = Parser.parse(firrtlSource, firrtlConfig.infoMode) + val annos = getAnnotations(optionsManager) // Does this need to be before calling compiler? optionsManager.makeTargetDir() - maybeFinalState = Some(firrtlConfig.compiler.compile( - CircuitState(parsedInput, ChirrtlForm, annos), + firrtlConfig.compiler.compile( + CircuitState(circuit, ChirrtlForm, annos), firrtlConfig.customTransforms - )) + ) } catch { // Rethrow the exceptions which are expected or due to the runtime environment (out of memory, stack overflow) @@ -213,8 +237,6 @@ object Driver { case e: Exception => throwInternalError(exception = Some(e)) } - val finalState = maybeFinalState.get - // Do emission // Note: Single emission target assumption is baked in here // Note: FirrtlExecutionSuccess emitted is only used if we're emitting the whole Circuit diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala index 3ee91da0..76426d1e 100644 --- a/src/main/scala/firrtl/ExecutionOptionsManager.scala +++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala @@ -4,6 +4,7 @@ package firrtl import firrtl.annotations._ import firrtl.Parser._ +import firrtl.ir.Circuit import firrtl.passes.memlib.{InferReadWriteAnnotation, ReplSeqMemAnnotation} import firrtl.passes.clocklist.ClockListAnnotation import logger.LogLevel @@ -184,7 +185,8 @@ case class FirrtlExecutionOptions( emitOneFilePerModule: Boolean = false, dontCheckCombLoops: Boolean = false, noDCE: Boolean = false, - annotationFileNames: List[String] = List.empty) + annotationFileNames: List[String] = List.empty, + firrtlCircuit: Option[Circuit] = None) extends ComposableOptions { require(!(emitOneFilePerModule && outputFileNameOverride.nonEmpty), |
