aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/scala/firrtl/ExecutionOptionsManager.scala705
-rw-r--r--src/main/scala/firrtl/options/StageAnnotations.scala1
-rw-r--r--src/main/scala/firrtl/stage/FirrtlAnnotations.scala1
-rw-r--r--src/main/scala/firrtl/stage/package.scala37
-rw-r--r--src/main/scala/firrtl/stage/phases/DriverCompatibility.scala10
-rw-r--r--src/main/scala/logger/Logger.scala63
-rw-r--r--src/main/scala/logger/LoggerAnnotations.scala2
-rw-r--r--src/test/scala/firrtlTests/ExecutionOptionsManagerSpec.scala54
-rw-r--r--src/test/scala/firrtlTests/ParserSpec.scala3
-rw-r--r--src/test/scala/loggertests/LoggerSpec.scala20
10 files changed, 15 insertions, 881 deletions
diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala
deleted file mode 100644
index b8c0dedd..00000000
--- a/src/main/scala/firrtl/ExecutionOptionsManager.scala
+++ /dev/null
@@ -1,705 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package firrtl
-
-import logger.LogLevel
-import logger.{ClassLogLevelAnnotation, LogClassNamesAnnotation, LogFileAnnotation, LogLevelAnnotation}
-import firrtl.annotations._
-import firrtl.Parser.{AppendInfo, GenInfo, IgnoreInfo, InfoMode, UseInfo}
-import firrtl.ir.Circuit
-import firrtl.passes.memlib.{InferReadWriteAnnotation, ReplSeqMemAnnotation}
-import firrtl.passes.clocklist.ClockListAnnotation
-import firrtl.transforms.NoCircuitDedupAnnotation
-import scopt.OptionParser
-import firrtl.stage.{
- CompilerAnnotation,
- FirrtlCircuitAnnotation,
- FirrtlFileAnnotation,
- FirrtlSourceAnnotation,
- InfoModeAnnotation,
- OutputFileAnnotation,
- RunFirrtlTransformAnnotation
-}
-import firrtl.stage.phases.DriverCompatibility.{EmitOneFilePerModuleAnnotation, TopNameAnnotation}
-import firrtl.options.{InputAnnotationFileAnnotation, OutputAnnotationFileAnnotation, ProgramArgsAnnotation, StageUtils}
-import firrtl.transforms.{DontCheckCombLoopsAnnotation, NoDCEAnnotation}
-
-import scala.collection.Seq
-
-/**
- * Use this trait to define an options class that can add its private command line options to a externally
- * declared parser.
- * '''NOTE''' In all derived trait/classes, if you intend on maintaining backwards compatibility,
- * be sure to add new options at the end of the current ones and don't remove any existing ones.
- */
-@deprecated("Use firrtl.options.HasScoptOptions and/or library/transform registration", "FIRRTL 1.2")
-trait ComposableOptions
-
-@deprecated("Use firrtl.options.{ExecutionOptionsManager, TerminateOnExit, DuplicateHandling}", "FIRRTL 1.2")
-abstract class HasParser(applicationName: String) {
- final val parser = new OptionParser[Unit](applicationName) {
- var terminateOnExit = true
- override def terminate(exitState: Either[String, Unit]): Unit = {
- if (terminateOnExit) sys.exit(0)
- }
- }
-
- /**
- * By default scopt calls sys.exit when --help is in options, this defeats that
- */
- def doNotExitOnHelp(): Unit = {
- parser.terminateOnExit = false
- }
-
- /**
- * By default scopt calls sys.exit when --help is in options, this un-defeats doNotExitOnHelp
- */
- def exitOnHelp(): Unit = {
- parser.terminateOnExit = true
- }
-}
-
-/**
- * Most of the chisel toolchain components require a topName which defines a circuit or a device under test.
- * Much of the work that is done takes place in a directory.
- * It would be simplest to require topName to be defined but in practice it is preferred to defer this.
- * For example, in chisel, by deferring this it is possible for the execute there to first elaborate the
- * circuit and then set the topName from that if it has not already been set.
- */
-@deprecated("Use a FirrtlOptionsView, LoggerOptionsView, or construct your own view of an AnnotationSeq", "FIRRTL 1.2")
-case class CommonOptions(
- topName: String = "",
- targetDirName: String = ".",
- globalLogLevel: LogLevel.Value = LogLevel.None,
- logToFile: Boolean = false,
- logClassNames: Boolean = false,
- classLogLevels: Map[String, LogLevel.Value] = Map.empty,
- programArgs: Seq[String] = Seq.empty)
- extends ComposableOptions {
-
- def getLogFileName(optionsManager: ExecutionOptionsManager): String = {
- if (topName.isEmpty) {
- optionsManager.getBuildFileName("log", "firrtl")
- } else {
- optionsManager.getBuildFileName("log")
- }
- }
-
- def toAnnotations: AnnotationSeq = List() ++ (if (topName.nonEmpty) Seq(TopNameAnnotation(topName)) else Seq()) ++
- (if (targetDirName != ".") Some(TargetDirAnnotation(targetDirName)) else None) ++
- Some(LogLevelAnnotation(globalLogLevel)) ++
- (if (logToFile) { Some(LogFileAnnotation(None)) }
- else { None }) ++
- (if (logClassNames) { Some(LogClassNamesAnnotation) }
- else { None }) ++
- classLogLevels.map { case (c, v) => ClassLogLevelAnnotation(c, v) } ++
- programArgs.map(a => ProgramArgsAnnotation(a))
-}
-
-@deprecated("Specify command line arguments in an Annotation mixing in HasScoptOptions", "FIRRTL 1.2")
-trait HasCommonOptions {
- self: ExecutionOptionsManager =>
- var commonOptions = CommonOptions()
-
- parser.note("common options")
-
- parser
- .opt[String]("top-name")
- .abbr("tn")
- .valueName("<top-level-circuit-name>")
- .foreach { x =>
- commonOptions = commonOptions.copy(topName = x)
- }
- .text("This options defines the top level circuit, defaults to dut when possible")
-
- parser
- .opt[String]("target-dir")
- .abbr("td")
- .valueName("<target-directory>")
- .foreach { x =>
- commonOptions = commonOptions.copy(targetDirName = x)
- }
- .text(s"This options defines a work directory for intermediate files, default is ${commonOptions.targetDirName}")
-
- parser
- .opt[String]("log-level")
- .abbr("ll")
- .valueName("<error|warn|info|debug|trace>")
- .foreach { x =>
- val level = x.toLowerCase match {
- case "error" => LogLevel.Error
- case "warn" => LogLevel.Warn
- case "info" => LogLevel.Info
- case "debug" => LogLevel.Debug
- case "trace" => LogLevel.Trace
- }
- commonOptions = commonOptions.copy(globalLogLevel = level)
- }
- .validate { x =>
- if (Array("error", "warn", "info", "debug", "trace").contains(x.toLowerCase)) parser.success
- else parser.failure(s"$x bad value must be one of error|warn|info|debug|trace")
- }
- .text(s"This options defines global log level, default is ${commonOptions.globalLogLevel}")
-
- parser
- .opt[Seq[String]]("class-log-level")
- .abbr("cll")
- .valueName("<FullClassName:[error|warn|info|debug|trace]>[,...]")
- .foreach { x =>
- val logAssignments = x.map { y =>
- val className :: levelName :: _ = y.split(":").toList
-
- val level = levelName.toLowerCase match {
- case "error" => LogLevel.Error
- case "warn" => LogLevel.Warn
- case "info" => LogLevel.Info
- case "debug" => LogLevel.Debug
- case "trace" => LogLevel.Trace
- case _ =>
- throw new Exception(s"Error: bad command line arguments for --class-log-level $x")
- }
- className -> level
- }
-
- commonOptions = commonOptions.copy(classLogLevels = commonOptions.classLogLevels ++ logAssignments)
-
- }
- .text(s"This options defines class log level, default is ${commonOptions.classLogLevels}")
-
- parser
- .opt[Unit]("log-to-file")
- .abbr("ltf")
- .foreach { _ =>
- commonOptions = commonOptions.copy(logToFile = true)
- }
- .text(s"default logs to stdout, this flags writes to topName.log or firrtl.log if no topName")
-
- parser
- .opt[Unit]("log-class-names")
- .abbr("lcn")
- .foreach { _ =>
- commonOptions = commonOptions.copy(logClassNames = true)
- }
- .text(s"shows class names and log level in logging output, useful for target --class-log-level")
-
- parser.help("help").text("prints this usage text")
-
- parser
- .arg[String]("<arg>...")
- .unbounded()
- .optional()
- .action((x, c) => commonOptions = commonOptions.copy(programArgs = commonOptions.programArgs :+ x))
- .text("optional unbounded args")
-
-}
-
-/** 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
- *
- * @param inputFileNameOverride default is targetDir/topName.fir
- * @param outputFileNameOverride default is targetDir/topName.v the .v is based on the compilerName parameter
- * @param compilerName which compiler to use
- * @param annotations annotations to pass to compiler
- */
-@deprecated("Use a FirrtlOptionsView or construct your own view of an AnnotationSeq", "FIRRTL 1.2")
-case class FirrtlExecutionOptions(
- inputFileNameOverride: String = "",
- outputFileNameOverride: String = "",
- compilerName: String = "verilog",
- infoModeName: String = "append",
- inferRW: Seq[String] = Seq.empty,
- firrtlSource: Option[String] = None,
- customTransforms: Seq[Transform] = List.empty,
- annotations: List[Annotation] = List.empty,
- annotationFileNameOverride: String = "",
- outputAnnotationFileName: String = "",
- emitOneFilePerModule: Boolean = false,
- dontCheckCombLoops: Boolean = false,
- noDCE: Boolean = false,
- annotationFileNames: List[String] = List.empty,
- firrtlCircuit: Option[Circuit] = None)
- 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
- case "ignore" => IgnoreInfo
- case "gen" => GenInfo(inputFileNameOverride)
- case "append" => AppendInfo(inputFileNameOverride)
- case other => UseInfo
- }
- }
-
- def compiler: Compiler = {
- compilerName match {
- case "none" => new NoneCompiler()
- case "high" => new HighFirrtlCompiler()
- case "low" => new LowFirrtlCompiler()
- case "middle" => new MiddleFirrtlCompiler()
- case "verilog" => new VerilogCompiler()
- case "mverilog" => new MinimumVerilogCompiler()
- case "sverilog" => new SystemVerilogCompiler()
- }
- }
-
- def outputSuffix: String = {
- compilerName match {
- case "verilog" | "mverilog" => "v"
- case "sverilog" => "sv"
- case "low" => "lo.fir"
- case "middle" => "mid.fir"
- case "high" => "hi.fir"
- case "none" => "fir"
- case _ =>
- throw new Exception(s"Illegal compiler name $compilerName")
- }
- }
-
- /** Get the name of the input file
- *
- * @note Does not implicitly add a file extension to the input file
- * @param optionsManager this is needed to access build function and its common options
- * @return a properly constructed input file name
- */
- def getInputFileName(optionsManager: ExecutionOptionsManager): String = {
- if (inputFileNameOverride.nonEmpty) inputFileNameOverride
- else optionsManager.getBuildFileName("fir", inputFileNameOverride)
- }
-
- /** Get the user-specified [[OutputConfig]]
- *
- * @param optionsManager this is needed to access build function and its common options
- * @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 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 "none" => classOf[ChirrtlEmitter]
- case "high" => classOf[HighFirrtlEmitter]
- case "middle" => classOf[MiddleFirrtlEmitter]
- case "low" => classOf[LowFirrtlEmitter]
- case "verilog" => classOf[VerilogEmitter]
- case "mverilog" => classOf[MinimumVerilogEmitter]
- case "sverilog" => classOf[VerilogEmitter]
- }
- getOutputConfig(optionsManager) match {
- case SingleFile(_) => Seq(EmitCircuitAnnotation(emitter))
- case OneFilePerModule(_) => Seq(EmitAllModulesAnnotation(emitter))
- }
- }
-
- /**
- * build the annotation file name, taking overriding parameters
- *
- * @param optionsManager this is needed to access build function and its common options
- * @return
- */
- @deprecated("Use FirrtlOptions.annotationFileNames instead", "FIRRTL 1.1")
- def getAnnotationFileName(optionsManager: ExecutionOptionsManager): String = {
- optionsManager.getBuildFileName("anno", annotationFileNameOverride)
- }
-
- def toAnnotations: AnnotationSeq = {
- if (inferRW.nonEmpty) {
- StageUtils.dramaticWarning("User set FirrtlExecutionOptions.inferRW, but inferRW has no effect!")
- }
-
- List() ++ (if (inputFileNameOverride.nonEmpty) Seq(FirrtlFileAnnotation(inputFileNameOverride)) else Seq()) ++
- (if (outputFileNameOverride.nonEmpty) { Some(OutputFileAnnotation(outputFileNameOverride)) }
- else { None }) ++
- Some(RunFirrtlTransformAnnotation.stringToEmitter(compilerName)) ++
- Some(InfoModeAnnotation(infoModeName)) ++
- firrtlSource.map(FirrtlSourceAnnotation(_)) ++
- customTransforms.map(t => RunFirrtlTransformAnnotation(t)) ++
- annotations ++
- (if (annotationFileNameOverride.nonEmpty) { Some(InputAnnotationFileAnnotation(annotationFileNameOverride)) }
- else { None }) ++
- (if (outputAnnotationFileName.nonEmpty) { Some(OutputAnnotationFileAnnotation(outputAnnotationFileName)) }
- else { None }) ++
- (if (emitOneFilePerModule) { Some(EmitOneFilePerModuleAnnotation) }
- else { None }) ++
- (if (dontCheckCombLoops) { Some(DontCheckCombLoopsAnnotation) }
- else { None }) ++
- (if (noDCE) { Some(NoDCEAnnotation) }
- else { None }) ++
- annotationFileNames.map(InputAnnotationFileAnnotation(_)) ++
- firrtlCircuit.map(FirrtlCircuitAnnotation(_))
- }
-}
-
-@deprecated("Specify command line arguments in an Annotation mixing in HasScoptOptions", "FIRRTL 1.2")
-trait HasFirrtlOptions {
- self: ExecutionOptionsManager =>
- var firrtlOptions = FirrtlExecutionOptions()
-
- parser.note("firrtl options")
-
- parser
- .opt[String]("input-file")
- .abbr("i")
- .valueName("<firrtl-source>")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(inputFileNameOverride = x)
- }
- .text {
- "use this to override the default input file name , default is empty"
- }
-
- parser
- .opt[String]("output-file")
- .abbr("o")
- .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"
- }
-
- parser
- .opt[String]("annotation-file")
- .abbr("faf")
- .unbounded()
- .valueName("<input-anno-file>")
- .foreach { x =>
- val annoFiles = x +: firrtlOptions.annotationFileNames
- firrtlOptions = firrtlOptions.copy(annotationFileNames = annoFiles)
- }
- .text("Used to specify annotation files (can appear multiple times)")
-
- parser
- .opt[Unit]("force-append-anno-file")
- .abbr("ffaaf")
- .hidden()
- .foreach { _ =>
- val msg = "force-append-anno-file is deprecated and will soon be removed\n" +
- (" " * 9) + "(It does not do anything anymore)"
- StageUtils.dramaticWarning(msg)
- }
-
- parser
- .opt[String]("output-annotation-file")
- .abbr("foaf")
- .valueName("<output-anno-file>")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(outputAnnotationFileName = x)
- }
- .text {
- "use this to set the annotation output file"
- }
-
- parser
- .opt[String]("compiler")
- .abbr("X")
- .valueName("<high|middle|low|verilog|mverilog|sverilog|none>")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(compilerName = x)
- }
- .validate { x =>
- if (Array("high", "middle", "low", "verilog", "mverilog", "sverilog", "none").contains(x.toLowerCase)) {
- parser.success
- } else {
- parser.failure(s"$x not a legal compiler")
- }
- }
- .text {
- s"compiler to use, default is ${firrtlOptions.compilerName}"
- }
-
- parser
- .opt[String]("info-mode")
- .valueName("<ignore|use|gen|append>")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(infoModeName = x.toLowerCase)
- }
- .validate { x =>
- if (Array("ignore", "use", "gen", "append").contains(x.toLowerCase)) parser.success
- else parser.failure(s"$x bad value must be one of ignore|use|gen|append")
- }
- .text {
- s"specifies the source info handling, default is ${firrtlOptions.infoModeName}"
- }
-
- parser
- .opt[Seq[String]]("custom-transforms")
- .abbr("fct")
- .valueName("<package>.<class>")
- .foreach { customTransforms: Seq[String] =>
- firrtlOptions = firrtlOptions.copy(
- customTransforms = firrtlOptions.customTransforms ++
- (customTransforms.map { x: String =>
- Class.forName(x).asInstanceOf[Class[_ <: Transform]].newInstance()
- })
- )
- }
- .text {
- """runs these custom transforms during compilation."""
- }
-
- parser
- .opt[Seq[String]]("inline")
- .abbr("fil")
- .valueName("<circuit>[.<module>[.<instance>]][,..],")
- .foreach { x =>
- val newAnnotations = x.map { value =>
- value.split('.') match {
- case Array(circuit) =>
- passes.InlineAnnotation(CircuitName(circuit))
- case Array(circuit, module) =>
- passes.InlineAnnotation(ModuleName(module, CircuitName(circuit)))
- case Array(circuit, module, inst) =>
- passes.InlineAnnotation(ComponentName(inst, ModuleName(module, CircuitName(circuit))))
- }
- }
- firrtlOptions = firrtlOptions.copy(
- annotations = firrtlOptions.annotations ++ newAnnotations,
- customTransforms = firrtlOptions.customTransforms :+ new passes.InlineInstances
- )
- }
- .text {
- """Inline one or more module (comma separated, no spaces) module looks like "MyModule" or "MyModule.myinstance"""
- }
-
- parser
- .opt[Unit]("infer-rw")
- .abbr("firw")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(
- annotations = firrtlOptions.annotations :+ InferReadWriteAnnotation,
- customTransforms = firrtlOptions.customTransforms :+ new passes.memlib.InferReadWrite
- )
- }
- .text {
- "Enable readwrite port inference for the target circuit"
- }
-
- parser
- .opt[String]("repl-seq-mem")
- .abbr("frsq")
- .valueName("-c:<circuit>:-i:<filename>:-o:<filename>")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(
- annotations = firrtlOptions.annotations :+ ReplSeqMemAnnotation.parse(x),
- customTransforms = firrtlOptions.customTransforms :+ new passes.memlib.ReplSeqMem
- )
- }
- .text {
- "Replace sequential memories with blackboxes + configuration file"
- }
-
- parser
- .opt[String]("list-clocks")
- .abbr("clks")
- .valueName("-c:<circuit>:-m:<module>:-o:<filename>")
- .foreach { x =>
- firrtlOptions = firrtlOptions.copy(
- annotations = firrtlOptions.annotations :+ ClockListAnnotation.parse(x),
- customTransforms = firrtlOptions.customTransforms :+ new passes.clocklist.ClockListTransform
- )
- }
- .text {
- "List which signal drives each clock of every descendent of specified module"
- }
-
- 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
- .opt[Unit]("no-check-comb-loops")
- .foreach { _ =>
- firrtlOptions = firrtlOptions.copy(dontCheckCombLoops = true)
- }
- .text {
- "Do NOT check for combinational loops (not recommended)"
- }
-
- parser
- .opt[Unit]("no-dce")
- .foreach { _ =>
- firrtlOptions = firrtlOptions.copy(noDCE = true)
- }
- .text {
- "Do NOT run dead code elimination"
- }
-
- parser
- .opt[Unit]("no-dedup")
- .foreach { _ =>
- firrtlOptions = firrtlOptions.copy(
- annotations = firrtlOptions.annotations :+ NoCircuitDedupAnnotation
- )
- }
- .text {
- "Do NOT dedup modules"
- }
-
- parser.note("")
-}
-
-@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2")
-sealed trait FirrtlExecutionResult
-
-@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2")
-object FirrtlExecutionSuccess {
- def apply(
- emitType: String,
- emitted: String,
- circuitState: CircuitState
- ): FirrtlExecutionSuccess = new FirrtlExecutionSuccess(emitType, emitted, circuitState)
-
- def unapply(arg: FirrtlExecutionSuccess): Option[(String, String)] = {
- Some((arg.emitType, arg.emitted))
- }
-}
-
-/**
- * Indicates a successful execution of the firrtl compiler, returning the compiled result and
- * the type of compile
- *
- * @param emitType The name of the compiler used, currently "high", "middle", "low", "verilog", "mverilog", or
- * "sverilog"
- * @param emitted The emitted result of compilation
- */
-@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2")
-class FirrtlExecutionSuccess(
- val emitType: String,
- val emitted: String,
- val circuitState: CircuitState)
- extends FirrtlExecutionResult
-
-/**
- * The firrtl compilation failed.
- *
- * @param message Some kind of hint as to what went wrong.
- */
-@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2")
-case class FirrtlExecutionFailure(message: String) extends FirrtlExecutionResult
-
-/**
- * @param applicationName The name shown in the usage
- */
-@deprecated("Use new FirrtlStage infrastructure", "FIRRTL 1.2")
-class ExecutionOptionsManager(val applicationName: String) extends HasParser(applicationName) with HasCommonOptions {
-
- def parse(args: Array[String]): Boolean = {
- parser.parse(args)
- }
-
- def showUsageAsError(): Unit = parser.showUsageAsError()
-
- /**
- * make sure that all levels of targetDirName exist
- *
- * @return true if directory exists
- */
- def makeTargetDir(): Boolean = {
- FileUtils.makeDirectory(commonOptions.targetDirName)
- }
-
- def targetDirName: String = commonOptions.targetDirName
-
- /**
- * this function sets the topName in the commonOptions.
- * It would be nicer to not need this but many chisel tools cannot determine
- * the name of the device under test until other options have been parsed.
- * Havin this function allows the code to set the TopName after it has been
- * determined
- *
- * @param newTopName the topName to be used
- */
- def setTopName(newTopName: String): Unit = {
- commonOptions = commonOptions.copy(topName = newTopName)
- }
- def setTopNameIfNotSet(newTopName: String): Unit = {
- if (commonOptions.topName.isEmpty) {
- setTopName(newTopName)
- }
- }
- def topName: String = commonOptions.topName
- def setTargetDirName(newTargetDirName: String): Unit = {
- commonOptions = commonOptions.copy(targetDirName = newTargetDirName)
- }
-
- /**
- * return a file based on targetDir, topName and suffix
- * Will not add the suffix if the topName already ends with that suffix
- *
- * @param suffix suffix to add, removes . if present
- * @param fileNameOverride this will override the topName if nonEmpty, when using this targetDir is ignored
- * @return
- */
- def getBuildFileName(suffix: String, fileNameOverride: String = ""): String = {
- makeTargetDir()
-
- val baseName = if (fileNameOverride.nonEmpty) fileNameOverride else topName
- val directoryName = {
- if (fileNameOverride.nonEmpty) {
- ""
- } else if (baseName.startsWith("./") || baseName.startsWith("/")) {
- ""
- } else {
- if (targetDirName.endsWith("/")) targetDirName else targetDirName + "/"
- }
- }
- val normalizedSuffix = {
- val dottedSuffix = if (suffix.startsWith(".")) suffix else s".$suffix"
- if (baseName.endsWith(dottedSuffix)) "" else dottedSuffix
- }
- val path = directoryName + baseName.split("/").dropRight(1).mkString("/")
- FileUtils.makeDirectory(path)
- s"$directoryName$baseName$normalizedSuffix"
- }
-}
diff --git a/src/main/scala/firrtl/options/StageAnnotations.scala b/src/main/scala/firrtl/options/StageAnnotations.scala
index 584f2842..1642e248 100644
--- a/src/main/scala/firrtl/options/StageAnnotations.scala
+++ b/src/main/scala/firrtl/options/StageAnnotations.scala
@@ -138,7 +138,6 @@ object ProgramArgsAnnotation {
}
/** Holds a filename containing one or more [[annotations.Annotation]] to be read
- * - this is not stored in [[FirrtlExecutionOptions]]
* - set with `-faf/--annotation-file`
* @param value input annotation filename
*/
diff --git a/src/main/scala/firrtl/stage/FirrtlAnnotations.scala b/src/main/scala/firrtl/stage/FirrtlAnnotations.scala
index 6dbb0434..515c8af9 100644
--- a/src/main/scala/firrtl/stage/FirrtlAnnotations.scala
+++ b/src/main/scala/firrtl/stage/FirrtlAnnotations.scala
@@ -208,7 +208,6 @@ object CompilerAnnotation extends HasShellOptions {
}
/** Holds the unambiguous class name of a [[Transform]] to run
- * - will be append to [[FirrtlExecutionOptions.customTransforms]]
* - set with `-fct/--custom-transforms`
* @param transform the full class name of the transform
*/
diff --git a/src/main/scala/firrtl/stage/package.scala b/src/main/scala/firrtl/stage/package.scala
index b3fe2473..b409fba3 100644
--- a/src/main/scala/firrtl/stage/package.scala
+++ b/src/main/scala/firrtl/stage/package.scala
@@ -39,41 +39,4 @@ package object stage {
}
}
}
-
- private[firrtl] implicit object FirrtlExecutionResultView
- extends OptionsView[FirrtlExecutionResult]
- with LazyLogging {
-
- def view(options: AnnotationSeq): FirrtlExecutionResult = {
- val emittedRes = options.collect { case a: EmittedAnnotation[_] => a.value.value }
- .mkString("\n")
-
- val emitters = options.collect { case RunFirrtlTransformAnnotation(e: Emitter) => e }
- if (emitters.length > 1) {
- logger.warn(
- "More than one emitter used which cannot be accurately represented" +
- "in the deprecated FirrtlExecutionResult: " + emitters.map(_.name).mkString(", ")
- )
- }
- val compilers = options.collect { case CompilerAnnotation(c) => c }
- val emitType = emitters.headOption.orElse(compilers.headOption).map(_.name).getOrElse("N/A")
- val form = emitters.headOption.orElse(compilers.headOption).map(_.outputForm).getOrElse(UnknownForm)
-
- options.collectFirst { case a: FirrtlCircuitAnnotation => a.circuit } match {
- case None => FirrtlExecutionFailure("No circuit found in AnnotationSeq!")
- case Some(a) =>
- FirrtlExecutionSuccess(
- emitType = emitType,
- emitted = emittedRes,
- circuitState = CircuitState(
- circuit = a,
- form = form,
- annotations = options,
- renames = None
- )
- )
- }
- }
- }
-
}
diff --git a/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala b/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala
index a18fe08d..546a18f5 100644
--- a/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala
+++ b/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala
@@ -4,7 +4,7 @@ package firrtl.stage.phases
import firrtl.stage._
-import firrtl.{AnnotationSeq, EmitAllModulesAnnotation, EmitCircuitAnnotation, Emitter, FirrtlExecutionResult, Parser}
+import firrtl.{AnnotationSeq, EmitAllModulesAnnotation, EmitCircuitAnnotation, Emitter, Parser}
import firrtl.annotations.NoTargetAnnotation
import firrtl.FileUtils
import firrtl.proto.FromProto
@@ -36,14 +36,6 @@ object DriverCompatibility {
s"""|Option '$a' was removed as part of the FIRRTL Stage refactor. Use an explicit input/output options instead.
|This error will be removed in 1.3.""".stripMargin
- /** Convert an [[firrtl.AnnotationSeq AnnotationSeq]] to a ''deprecated'' [[firrtl.FirrtlExecutionResult
- * FirrtlExecutionResult]].
- * @param annotations a sequence of [[firrtl.annotations.Annotation Annotation]]
- */
- @deprecated("FirrtlExecutionResult is deprecated as part of the Stage/Phase refactor. Migrate to FirrtlStage.", "1.2")
- def firrtlResultView(annotations: AnnotationSeq): FirrtlExecutionResult =
- Viewer[FirrtlExecutionResult].view(annotations)
-
/** Holds the name of the top (main) module in an input circuit
* @param value top module name
*/
diff --git a/src/main/scala/logger/Logger.scala b/src/main/scala/logger/Logger.scala
index 09fc0924..f14eec71 100644
--- a/src/main/scala/logger/Logger.scala
+++ b/src/main/scala/logger/Logger.scala
@@ -4,7 +4,7 @@ package logger
import java.io.{ByteArrayOutputStream, File, FileOutputStream, PrintStream}
-import firrtl.{AnnotationSeq, ExecutionOptionsManager}
+import firrtl.AnnotationSeq
import firrtl.options.Viewer.view
import logger.phases.{AddDefaults, Checks}
@@ -13,8 +13,6 @@ import scala.util.DynamicVariable
/**
* This provides a facility for a log4scala* type logging system. Why did we write our own? Because
* the canned ones are just too darned hard to turn on, particularly when embedded in a distribution.
- * This one can be turned on programmatically or with the options exposed in the [[firrtl.CommonOptions]]
- * and [[ExecutionOptionsManager]] APIs in firrtl.
* There are 4 main options:
* * A simple global option to turn on all in scope (and across threads, might want to fix this)
* * Turn on specific levels for specific fully qualified class names
@@ -30,8 +28,11 @@ import scala.util.DynamicVariable
* The supported log levels, what do they mean? Whatever you want them to.
*/
object LogLevel extends Enumeration {
+ // None indicates "not set"
val Error, Warn, Info, Debug, Trace, None = Value
+ def default = Warn
+
def apply(s: String): LogLevel.Value = s.toLowerCase match {
case "error" => LogLevel.Error
case "warn" => LogLevel.Warn
@@ -55,7 +56,7 @@ trait LazyLogging {
* when used in multi-threaded environments
*/
private class LoggerState {
- var globalLevel = LogLevel.Warn
+ var globalLevel = LogLevel.None
val classLevels = new scala.collection.mutable.HashMap[String, LogLevel.Value]
val classToLevelCache = new scala.collection.mutable.HashMap[String, LogLevel.Value]
var logClassNames = false
@@ -114,44 +115,13 @@ object Logger {
}
}
- /**
- * This creates a block of code that will have access to the
- * thread specific logger. The state will be set according to the
- * logging options set in the common options of the manager
- * @param manager source of logger settings
- * @param codeBlock code to be run with these logger settings
- * @tparam A The return type of codeBlock
- * @return Whatever block returns
- */
- @deprecated("Use makeScope(opts: FirrtlOptions)", "FIRRTL 1.2")
- def makeScope[A](manager: ExecutionOptionsManager)(codeBlock: => A): A =
- makeScope(manager.commonOptions.toAnnotations)(codeBlock)
-
- /**
- * See makeScope using manager. This creates a manager from a command line arguments style
- * list of strings
- * @param args List of strings
- * @param codeBlock the block to call
- * @tparam A return type of codeBlock
- * @return
- */
- @deprecated("Use makescope(opts: FirrtlOptions)", "FIRRTL 1.2")
- def makeScope[A](args: Array[String] = Array.empty)(codeBlock: => A): A = {
- val executionOptionsManager = new ExecutionOptionsManager("logger")
- if (executionOptionsManager.parse(args)) {
- makeScope(executionOptionsManager)(codeBlock)
- } else {
- throw new Exception(s"logger invoke failed to parse args ${args.mkString(", ")}")
- }
- }
-
/** Set a scope for this logger based on available annotations
* @param options a sequence annotations
* @param codeBlock some Scala code over which to define this scope
* @tparam A return type of the code block
* @return the original return of the code block
*/
- def makeScope[A](options: AnnotationSeq)(codeBlock: => A): A = {
+ def makeScope[A](options: AnnotationSeq = Seq.empty)(codeBlock: => A): A = {
val runState: LoggerState = {
val newRunState = updatableLoggerState.value.getOrElse(new LoggerState)
if (newRunState.fromInvoke) {
@@ -237,17 +207,16 @@ object Logger {
case Some(true) => logIt()
case Some(false) =>
case None =>
- if (
- (state.globalLevel == LogLevel.None && level == LogLevel.Error) ||
- (state.globalLevel != LogLevel.None && state.globalLevel >= level)
- ) {
+ if (getGlobalLevel >= level) {
logIt()
}
}
}
- def getGlobalLevel: LogLevel.Value = {
- state.globalLevel
+ def getGlobalLevel: LogLevel.Value = state.globalLevel match {
+ // None means "not set" so use default in that case
+ case LogLevel.None => LogLevel.default
+ case other => other
}
/**
@@ -349,15 +318,6 @@ object Logger {
state.classLevels ++= namesToLevel
}
- /**
- * This is used to set the options that have been set in a optionsManager or are coming
- * from the command line via an options manager
- * @param optionsManager manager
- */
- @deprecated("Use setOptions(annotations: AnnotationSeq)", "FIRRTL 1.2")
- def setOptions(optionsManager: ExecutionOptionsManager): Unit =
- setOptions(optionsManager.commonOptions.toAnnotations)
-
/** Set logger options based on the content of an [[firrtl.AnnotationSeq AnnotationSeq]]
* @param inputAnnotations annotation sequence containing logger options
*/
@@ -372,7 +332,6 @@ object Logger {
case (x, LogLevel.None) => x
case (LogLevel.None, x) => x
case (_, x) => x
- case _ => LogLevel.Error
}
setClassLogLevels(lopts.classLogLevels)
diff --git a/src/main/scala/logger/LoggerAnnotations.scala b/src/main/scala/logger/LoggerAnnotations.scala
index c292db87..0185492e 100644
--- a/src/main/scala/logger/LoggerAnnotations.scala
+++ b/src/main/scala/logger/LoggerAnnotations.scala
@@ -13,7 +13,7 @@ sealed trait LoggerOption { this: Annotation => }
* - if unset, a [[LogLevelAnnotation]] with the default log level will be emitted
* @param level the level of logging
*/
-case class LogLevelAnnotation(globalLogLevel: LogLevel.Value = LogLevel.Warn)
+case class LogLevelAnnotation(globalLogLevel: LogLevel.Value = LogLevel.None)
extends NoTargetAnnotation
with LoggerOption
diff --git a/src/test/scala/firrtlTests/ExecutionOptionsManagerSpec.scala b/src/test/scala/firrtlTests/ExecutionOptionsManagerSpec.scala
deleted file mode 100644
index f176fe38..00000000
--- a/src/test/scala/firrtlTests/ExecutionOptionsManagerSpec.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package firrtlTests
-
-import firrtl._
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class ExecutionOptionsManagerSpec extends AnyFreeSpec with Matchers {
- "ExecutionOptionsManager is a container for one more more ComposableOptions Block" - {
- "It has a default CommonOptionsBlock" in {
- val manager = new ExecutionOptionsManager("test")
- manager.topName should be("")
- manager.targetDirName should be(".")
- manager.commonOptions.topName should be("")
- manager.commonOptions.targetDirName should be(".")
- }
- "But can override defaults like this" in {
- val manager = new ExecutionOptionsManager("test") {
- commonOptions = CommonOptions(topName = "dog", targetDirName = "a/b/c")
- }
- manager.commonOptions shouldBe a[CommonOptions]
- manager.topName should be("dog")
- manager.targetDirName should be("a/b/c")
- manager.commonOptions.topName should be("dog")
- manager.commonOptions.targetDirName should be("a/b/c")
- }
- "The add method should put a new version of a given type the manager" in {
- val manager = new ExecutionOptionsManager("test") {
- commonOptions = CommonOptions(topName = "dog", targetDirName = "a/b/c")
- }
- val initialCommon = manager.commonOptions
- initialCommon.topName should be("dog")
- initialCommon.targetDirName should be("a/b/c")
-
- manager.commonOptions = CommonOptions(topName = "cat", targetDirName = "d/e/f")
-
- val afterCommon = manager.commonOptions
- afterCommon.topName should be("cat")
- afterCommon.targetDirName should be("d/e/f")
- initialCommon.topName should be("dog")
- initialCommon.targetDirName should be("a/b/c")
- }
- "multiple composable blocks should be separable" in {
- val manager = new ExecutionOptionsManager("test") with HasFirrtlOptions {
- commonOptions = CommonOptions(topName = "spoon")
- firrtlOptions = FirrtlExecutionOptions(inputFileNameOverride = "fork")
- }
-
- manager.firrtlOptions.inputFileNameOverride should be("fork")
- manager.commonOptions.topName should be("spoon")
- }
- }
-}
diff --git a/src/test/scala/firrtlTests/ParserSpec.scala b/src/test/scala/firrtlTests/ParserSpec.scala
index 57b468ea..89e73cb7 100644
--- a/src/test/scala/firrtlTests/ParserSpec.scala
+++ b/src/test/scala/firrtlTests/ParserSpec.scala
@@ -312,9 +312,6 @@ class ParserSpec extends FirrtlFlatSpec {
| bar.a <- a
| b <- bar.b
""".stripMargin
- val manager = new ExecutionOptionsManager("test") with HasFirrtlOptions {
- firrtlOptions = FirrtlExecutionOptions(firrtlSource = Some(input))
- }
a[SyntaxErrorsException] shouldBe thrownBy {
(new FirrtlStage).execute(Array(), Seq(FirrtlSourceAnnotation(input)))
}
diff --git a/src/test/scala/loggertests/LoggerSpec.scala b/src/test/scala/loggertests/LoggerSpec.scala
index d9feb931..e0a7b43d 100644
--- a/src/test/scala/loggertests/LoggerSpec.scala
+++ b/src/test/scala/loggertests/LoggerSpec.scala
@@ -41,7 +41,7 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"Logger is a simple but powerful logging system" - {
"Following tests show how global level can control logging" - {
- "setting level to None will result in only error messages" in {
+ "setting level to None will result in warn messages" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
@@ -52,7 +52,7 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
val messagesLogged = captor.getOutputAsString
messagesLogged.contains(LoggerSpec.ErrorMsg) should be(true)
- messagesLogged.contains(LoggerSpec.WarnMsg) should be(false)
+ messagesLogged.contains(LoggerSpec.WarnMsg) should be(true)
messagesLogged.contains(LoggerSpec.InfoMsg) should be(false)
messagesLogged.contains(LoggerSpec.DebugMsg) should be(false)
messagesLogged.contains(LoggerSpec.TraceMsg) should be(false)
@@ -274,22 +274,6 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
messagesLogged.contains("logger3") should be(true)
}
}
- "Show logging can be set with command options" in {
- val captor = new Logger.OutputCaptor
-
- Logger.makeScope(Array("--class-log-level", "loggertests.LogsInfo3:info")) {
- Logger.setOutput(captor.printStream)
- val r2 = new LogsInfo2
- val r3 = new LogsInfo3
- r2.run()
- r3.run()
-
- val messagesLogged = captor.getOutputAsString
-
- messagesLogged.contains("logger2") should be(false)
- messagesLogged.contains("logger3") should be(true)
- }
- }
"Show that printstream remains across makeScopes" in {
Logger.makeScope() {
val captor = new Logger.OutputCaptor