aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/scala/firrtl/Driver.scala19
-rw-r--r--src/main/scala/firrtl/Emitter.scala48
-rw-r--r--src/main/scala/firrtl/options/Phase.scala16
-rw-r--r--src/main/scala/firrtl/options/Registration.scala58
-rw-r--r--src/main/scala/firrtl/options/Shell.scala12
-rw-r--r--src/main/scala/firrtl/options/Stage.scala11
-rw-r--r--src/main/scala/firrtl/options/StageAnnotations.scala66
-rw-r--r--src/main/scala/firrtl/options/phases/DeletedWrapper.scala43
-rw-r--r--src/main/scala/firrtl/passes/Inline.scala36
-rw-r--r--src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala18
-rw-r--r--src/main/scala/firrtl/passes/memlib/InferReadWrite.scala17
-rw-r--r--src/main/scala/firrtl/passes/memlib/MemLibOptions.scala11
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala20
-rw-r--r--src/main/scala/firrtl/stage/FirrtlAnnotations.scala125
-rw-r--r--src/main/scala/firrtl/stage/FirrtlStage.scala23
-rw-r--r--src/main/scala/firrtl/stage/phases/DriverCompatibility.scala7
-rw-r--r--src/main/scala/firrtl/transforms/CheckCombLoops.scala12
-rw-r--r--src/main/scala/firrtl/transforms/DeadCodeElimination.scala12
-rw-r--r--src/main/scala/logger/Logger.scala6
-rw-r--r--src/main/scala/logger/LoggerAnnotations.scala77
-rw-r--r--src/test/scala/firrtlTests/options/RegistrationSpec.scala21
-rw-r--r--src/test/scala/firrtlTests/options/phases/ChecksSpec.scala4
-rw-r--r--src/test/scala/firrtlTests/options/phases/GetIncludesSpec.scala1
23 files changed, 379 insertions, 284 deletions
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala
index c8713e09..66e09e86 100644
--- a/src/main/scala/firrtl/Driver.scala
+++ b/src/main/scala/firrtl/Driver.scala
@@ -18,8 +18,8 @@ import firrtl.transforms._
import firrtl.Utils.throwInternalError
import firrtl.stage.{FirrtlExecutionResultView, FirrtlStage}
import firrtl.stage.phases.DriverCompatibility
-import firrtl.options.{StageUtils, Phase}
-import firrtl.options.Viewer
+import firrtl.options.{StageUtils, Phase, Viewer}
+import firrtl.options.phases.DeletedWrapper
/**
@@ -216,15 +216,16 @@ object Driver {
val annos = optionsManager.firrtlOptions.toAnnotations ++ optionsManager.commonOptions.toAnnotations
- val phases: Seq[Phase] = Seq(
- new DriverCompatibility.AddImplicitAnnotationFile,
- new DriverCompatibility.AddImplicitFirrtlFile,
- new DriverCompatibility.AddImplicitOutputFile,
- new DriverCompatibility.AddImplicitEmitter,
- new FirrtlStage )
+ val phases: Seq[Phase] =
+ Seq( new DriverCompatibility.AddImplicitAnnotationFile,
+ new DriverCompatibility.AddImplicitFirrtlFile,
+ new DriverCompatibility.AddImplicitOutputFile,
+ new DriverCompatibility.AddImplicitEmitter,
+ new FirrtlStage )
+ .map(DeletedWrapper(_))
val annosx = try {
- phases.foldLeft(annos)( (a, p) => p.runTransform(a) )
+ phases.foldLeft(annos)( (a, p) => p.transform(a) )
} catch {
case e: firrtl.options.OptionsException => return FirrtlExecutionFailure(e.message)
}
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala
index 44190b39..3bbba289 100644
--- a/src/main/scala/firrtl/Emitter.scala
+++ b/src/main/scala/firrtl/Emitter.scala
@@ -19,7 +19,7 @@ import firrtl.PrimOps._
import firrtl.WrappedExpression._
import Utils._
import MemPortUtils.{memPortField, memType}
-import firrtl.options.{HasScoptOptions, StageUtils, PhaseException}
+import firrtl.options.{HasShellOptions, ShellOption, StageUtils, PhaseException}
import firrtl.stage.RunFirrtlTransformAnnotation
import scopt.OptionParser
// Datastructures
@@ -34,14 +34,12 @@ sealed trait EmitAnnotation extends NoTargetAnnotation {
case class EmitCircuitAnnotation(emitter: Class[_ <: Emitter]) extends EmitAnnotation
case class EmitAllModulesAnnotation(emitter: Class[_ <: Emitter]) extends EmitAnnotation
-object EmitCircuitAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p
- .opt[String]("emit-circuit")
- .abbr("E")
- .valueName("<chirrtl|high|middle|low|verilog|mverilog|sverilog>")
- .unbounded()
- .action{ (x, c) =>
- val xx = x match {
+object EmitCircuitAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "emit-circuit",
+ toAnnotationSeq = (a: String) => a match {
case "chirrtl" => Seq(RunFirrtlTransformAnnotation(new ChirrtlEmitter),
EmitCircuitAnnotation(classOf[ChirrtlEmitter]))
case "high" => Seq(RunFirrtlTransformAnnotation(new HighFirrtlEmitter),
@@ -54,20 +52,19 @@ object EmitCircuitAnnotation extends HasScoptOptions {
EmitCircuitAnnotation(classOf[VerilogEmitter]))
case "sverilog" => Seq(RunFirrtlTransformAnnotation(new SystemVerilogEmitter),
EmitCircuitAnnotation(classOf[SystemVerilogEmitter]))
- case _ => throw new PhaseException(s"Unknown emitter '$x'! (Did you misspell it?)")
- }
- xx ++ c }
- .text("Run the specified circuit emitter (all modules in one file)")
+ case _ => throw new PhaseException(s"Unknown emitter '$a'! (Did you misspell it?)") },
+ helpText = "Run the specified circuit emitter (all modules in one file)",
+ shortOption = Some("E"),
+ helpValueName = Some("<chirrtl|high|middle|low|verilog|mverilog|sverilog>") ) )
+
}
-object EmitAllModulesAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p
- .opt[String]("emit-modules")
- .abbr("e")
- .valueName("<none|high|middle|low|verilog|mverilog|sverilog>")
- .unbounded()
- .action{ (x, c) =>
- val xx = x match {
+object EmitAllModulesAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "emit-modules",
+ toAnnotationSeq = (a: String) => a match {
case "chirrtl" => Seq(RunFirrtlTransformAnnotation(new ChirrtlEmitter),
EmitAllModulesAnnotation(classOf[ChirrtlEmitter]))
case "high" => Seq(RunFirrtlTransformAnnotation(new HighFirrtlEmitter),
@@ -80,10 +77,11 @@ object EmitAllModulesAnnotation extends HasScoptOptions {
EmitAllModulesAnnotation(classOf[VerilogEmitter]))
case "sverilog" => Seq(RunFirrtlTransformAnnotation(new SystemVerilogEmitter),
EmitAllModulesAnnotation(classOf[SystemVerilogEmitter]))
- case _ => throw new PhaseException(s"Unknown emitter '$x'! (Did you misspell it?)")
- }
- xx ++ c }
- .text("Run the specified module emitter (one file per module)")
+ case _ => throw new PhaseException(s"Unknown emitter '$a'! (Did you misspell it?)") },
+ helpText = "Run the specified module emitter (one file per module)",
+ shortOption = Some("e"),
+ helpValueName = Some("<chirrtl|high|middle|low|verilog|mverilog|sverilog>") ) )
+
}
// ***** Annotations for results of emission *****
diff --git a/src/main/scala/firrtl/options/Phase.scala b/src/main/scala/firrtl/options/Phase.scala
index a660d08a..34739053 100644
--- a/src/main/scala/firrtl/options/Phase.scala
+++ b/src/main/scala/firrtl/options/Phase.scala
@@ -39,22 +39,6 @@ abstract class Phase extends TransformLike[AnnotationSeq] {
*/
lazy val name: String = this.getClass.getName
- /** Perform the transform of [[transform]] on an [[firrtl.AnnotationSeq AnnotationSeq]] and add
- * [[firrtl.annotations.DeletedAnnotation DeletedAnnotation]]s for any deleted [[firrtl.annotations.Annotation
- * Annotation]]s.
- * @param a
- */
- final def runTransform(annotations: AnnotationSeq): AnnotationSeq = {
- val ax = transform(annotations)
-
- val (in, out) = (mutable.LinkedHashSet() ++ annotations, mutable.LinkedHashSet() ++ ax)
-
- (in -- out).map {
- case DeletedAnnotation(n, a) => DeletedAnnotation(s"$n+$name", a)
- case a => DeletedAnnotation(name, a)
- }.toSeq ++ ax
- }
-
}
/** A [[TransformLike]] that internally ''translates'' the input type to some other type, transforms the internal type,
diff --git a/src/main/scala/firrtl/options/Registration.scala b/src/main/scala/firrtl/options/Registration.scala
index a826ec50..c832ec7c 100644
--- a/src/main/scala/firrtl/options/Registration.scala
+++ b/src/main/scala/firrtl/options/Registration.scala
@@ -4,40 +4,70 @@ package firrtl.options
import firrtl.{AnnotationSeq, Transform}
-import scopt.OptionParser
+import scopt.{OptionDef, OptionParser, Read}
+
+/** Contains information about a [[Shell]] command line option
+ * @tparam the type of the command line argument
+ * @param longOption a long, double-dash option
+ * @param toAnnotationSeq a function to convert the type into an [[firrtl.AnnotationSeq AnnotationSeq]]
+ * @param helpText help text
+ * @param shortOption an optional single-dash option
+ * @param helpValueName a string to show as a placeholder argument in help text
+ */
+final class ShellOption[A: Read] (
+ val longOption: String,
+ val toAnnotationSeq: A => AnnotationSeq,
+ val helpText: String,
+ val shortOption: Option[String] = None,
+ val helpValueName: Option[String] = None
+) {
+
+ /** Add this specific shell (command line) option to an option parser
+ * @param p an option parser
+ */
+ final def addOption(p: OptionParser[AnnotationSeq]): Unit = {
+ val f = Seq(
+ (p: OptionDef[A, AnnotationSeq]) => p.action( (x, c) => toAnnotationSeq(x).reverse ++ c ),
+ (p: OptionDef[A, AnnotationSeq]) => p.text(helpText),
+ (p: OptionDef[A, AnnotationSeq]) => p.unbounded()) ++
+ shortOption.map( a => (p: OptionDef[A, AnnotationSeq]) => p.abbr(a) ) ++
+ helpValueName.map( a => (p: OptionDef[A, AnnotationSeq]) => p.valueName(a) )
+
+ f.foldLeft(p.opt[A](longOption))( (a, b) => b(a) )
+ }
+}
/** Indicates that this class/object includes options (but does not add these as a registered class)
*/
-trait HasScoptOptions {
+trait HasShellOptions {
- /** This method will be called to add options to an OptionParser ('''OPTIONS SHOULD BE PREPENDED''')
- *
- *
- * '''The ordering of [[firrtl.annotations.Annotation Annotation]] is important and has meaning for parallel
- * compilations. For deterministic behavior, you should always prepend any annotations to the [[firrtl.AnnotationSeq
- * AnnotationSeq]]. The [[firrtl.AnnotationSeq AnnotationSeq]] will be automatically reversed after a [[Stage]]
- * parses it.'''
- *
+ /** A sequence of options provided
+ */
+ def options: Seq[ShellOption[_]]
+
+ /** Add all shell (command line) options to an option parser
* @param p an option parser
*/
- def addOptions(p: OptionParser[AnnotationSeq]): Unit
+ final def addOptions(p: OptionParser[AnnotationSeq]): Unit = options.foreach(_.addOption(p))
+
}
-/** A [[Transform]] that includes options that should be exposed at the top level.
+/** A [[Transform]] that includes an option that should be exposed at the top level.
*
* @note To complete registration, include an entry in
* src/main/resources/META-INF/services/firrtl.options.RegisteredTransform */
-trait RegisteredTransform extends HasScoptOptions { this: Transform => }
+trait RegisteredTransform extends HasShellOptions { this: Transform => }
/** A class that includes options that should be exposed as a group at the top level.
*
* @note To complete registration, include an entry in
* src/main/resources/META-INF/services/firrtl.options.RegisteredLibrary */
-trait RegisteredLibrary extends HasScoptOptions {
+trait RegisteredLibrary extends HasShellOptions {
/** The name of this library.
*
* This will be used when generating help text.
*/
def name: String
+
}
diff --git a/src/main/scala/firrtl/options/Shell.scala b/src/main/scala/firrtl/options/Shell.scala
index dbc403a5..28c0554a 100644
--- a/src/main/scala/firrtl/options/Shell.scala
+++ b/src/main/scala/firrtl/options/Shell.scala
@@ -16,10 +16,10 @@ import java.util.ServiceLoader
class Shell(val applicationName: String) {
/** Command line argument parser (OptionParser) with modifications */
- final val parser = new OptionParser[AnnotationSeq](applicationName) with DuplicateHandling with ExceptOnError
+ protected val parser = new OptionParser[AnnotationSeq](applicationName) with DuplicateHandling with ExceptOnError
/** Contains all discovered [[RegisteredLibrary]] */
- lazy val registeredLibraries: Seq[RegisteredLibrary] = {
+ final lazy val registeredLibraries: Seq[RegisteredLibrary] = {
val libraries = scala.collection.mutable.ArrayBuffer[RegisteredLibrary]()
val iter = ServiceLoader.load(classOf[RegisteredLibrary]).iterator()
while (iter.hasNext) {
@@ -33,7 +33,7 @@ class Shell(val applicationName: String) {
}
/** Contains all discovered [[RegisteredTransform]] */
- lazy val registeredTransforms: Seq[RegisteredTransform] = {
+ final lazy val registeredTransforms: Seq[RegisteredTransform] = {
val transforms = scala.collection.mutable.ArrayBuffer[RegisteredTransform]()
val iter = ServiceLoader.load(classOf[RegisteredTransform]).iterator()
if (iter.hasNext) { parser.note("FIRRTL Transform Options") }
@@ -61,11 +61,11 @@ class Shell(val applicationName: String) {
}
parser.note("Shell Options")
+ ProgramArgsAnnotation.addOptions(parser)
Seq( TargetDirAnnotation,
- ProgramArgsAnnotation,
InputAnnotationFileAnnotation,
OutputAnnotationFileAnnotation )
- .map(_.addOptions(parser))
+ .foreach(_.addOptions(parser))
parser.opt[Unit]("show-registrations")
.action{ (_, c) =>
@@ -85,5 +85,5 @@ class Shell(val applicationName: String) {
ClassLogLevelAnnotation,
LogFileAnnotation,
LogClassNamesAnnotation )
- .map(_.addOptions(parser))
+ .foreach(_.addOptions(parser))
}
diff --git a/src/main/scala/firrtl/options/Stage.scala b/src/main/scala/firrtl/options/Stage.scala
index 38cc9d42..f2780761 100644
--- a/src/main/scala/firrtl/options/Stage.scala
+++ b/src/main/scala/firrtl/options/Stage.scala
@@ -31,16 +31,19 @@ abstract class Stage extends Phase {
* @throws OptionsException if command line or annotation validation fails
*/
final def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val annotationsx = Seq( new phases.GetIncludes,
- new phases.ConvertLegacyAnnotations )
- .foldLeft(annotations)((a, p) => p.runTransform(a))
+ val annotationsx =
+ Seq( new phases.GetIncludes,
+ new phases.ConvertLegacyAnnotations )
+ .map(phases.DeletedWrapper(_))
+ .foldLeft(annotations)((a, p) => p.transform(a))
Logger.makeScope(annotationsx) {
Seq( new phases.AddDefaults,
new phases.Checks,
new Phase { def transform(a: AnnotationSeq) = run(a) },
new phases.WriteOutputAnnotations )
- .foldLeft(annotationsx)((a, p) => p.runTransform(a))
+ .map(phases.DeletedWrapper(_))
+ .foldLeft(annotationsx)((a, p) => p.transform(a))
}
}
diff --git a/src/main/scala/firrtl/options/StageAnnotations.scala b/src/main/scala/firrtl/options/StageAnnotations.scala
index e8a1a288..e35a6afa 100644
--- a/src/main/scala/firrtl/options/StageAnnotations.scala
+++ b/src/main/scala/firrtl/options/StageAnnotations.scala
@@ -21,13 +21,16 @@ trait Unserializable { this: Annotation => }
*/
case class TargetDirAnnotation(directory: String = ".") extends NoTargetAnnotation with StageOption
-object TargetDirAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("target-dir")
- .abbr("td")
- .valueName("<target-directory>")
- .action( (x, c) => TargetDirAnnotation(x) +: c )
- .unbounded() // See [Note 1]
- .text(s"Work directory for intermediate files/blackboxes, default is '.' (current directory)")
+object TargetDirAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "target-dir",
+ toAnnotationSeq = (a: String) => Seq(TargetDirAnnotation(a)),
+ helpText = "Work directory (default: '.')",
+ shortOption = Some("td"),
+ helpValueName = Some("<directory>") ) )
+
}
/** Additional arguments
@@ -36,7 +39,8 @@ object TargetDirAnnotation extends HasScoptOptions {
*/
case class ProgramArgsAnnotation(arg: String) extends NoTargetAnnotation with StageOption
-object ProgramArgsAnnotation extends HasScoptOptions {
+object ProgramArgsAnnotation {
+
def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.arg[String]("<arg>...")
.unbounded()
.optional()
@@ -51,13 +55,16 @@ object ProgramArgsAnnotation extends HasScoptOptions {
*/
case class InputAnnotationFileAnnotation(file: String) extends NoTargetAnnotation with StageOption
-object InputAnnotationFileAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("annotation-file")
- .abbr("faf")
- .unbounded()
- .valueName("<input-anno-file>")
- .action( (x, c) => InputAnnotationFileAnnotation(x) +: c )
- .text("Used to specify annotation file")
+object InputAnnotationFileAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "annotation-file",
+ toAnnotationSeq = (a: String) => Seq(InputAnnotationFileAnnotation(a)),
+ helpText = "An input annotation file",
+ shortOption = Some("faf"),
+ helpValueName = Some("<file>") ) )
+
}
/** An explicit output _annotation_ file to write to
@@ -66,13 +73,16 @@ object InputAnnotationFileAnnotation extends HasScoptOptions {
*/
case class OutputAnnotationFileAnnotation(file: String) extends NoTargetAnnotation with StageOption
-object OutputAnnotationFileAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("output-annotation-file")
- .abbr("foaf")
- .valueName ("<output-anno-file>")
- .action( (x, c) => OutputAnnotationFileAnnotation(x) +: c )
- .unbounded()
- .text("use this to set the annotation output file")
+object OutputAnnotationFileAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "output-annotation-file",
+ toAnnotationSeq = (a: String) => Seq(OutputAnnotationFileAnnotation(a)),
+ helpText = "An output annotation file",
+ shortOption = Some("foaf"),
+ helpValueName = Some("<file>") ) )
+
}
/** If this [[firrtl.annotations.Annotation Annotation]] exists in an [[firrtl.AnnotationSeq AnnotationSeq]], then a
@@ -80,12 +90,12 @@ object OutputAnnotationFileAnnotation extends HasScoptOptions {
* [[firrtl.annotations.DeletedAnnotation DeletedAnnotation]]s when it writes to a file.
* - set with '--write-deleted'
*/
-case object WriteDeletedAnnotation extends NoTargetAnnotation with StageOption with HasScoptOptions {
+case object WriteDeletedAnnotation extends NoTargetAnnotation with StageOption with HasShellOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p
- .opt[Unit]("write-deleted")
- .unbounded()
- .action( (_, c) => WriteDeletedAnnotation +: c )
- .text("Include deleted annotations in the output annotation file")
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "write-deleted",
+ toAnnotationSeq = (_: Unit) => Seq(WriteDeletedAnnotation),
+ helpText = "Include deleted annotations in the output annotation file" ) )
}
diff --git a/src/main/scala/firrtl/options/phases/DeletedWrapper.scala b/src/main/scala/firrtl/options/phases/DeletedWrapper.scala
new file mode 100644
index 00000000..0a959f32
--- /dev/null
+++ b/src/main/scala/firrtl/options/phases/DeletedWrapper.scala
@@ -0,0 +1,43 @@
+// See LICENSE for license details.
+
+package firrtl.options.phases
+
+import firrtl.AnnotationSeq
+import firrtl.annotations.DeletedAnnotation
+import firrtl.options.{Phase, Translator}
+
+import scala.collection.mutable
+
+/** Wrap a [[firrtl.options.Phase Phase]] such that any [[firrtl.annotations.Annotation Annotation]] removed by the
+ * wrapped [[firrtl.options.Phase Phase]] will be added as [[firrtl.annotations.DeletedAnnotation DeletedAnnotation]]s.
+ * @param p a [[firrtl.options.Phase Phase]] to wrap
+ */
+class DeletedWrapper(p: Phase) extends Phase with Translator[AnnotationSeq, (AnnotationSeq, AnnotationSeq)] {
+
+ override lazy val name: String = p.name
+
+ def aToB(a: AnnotationSeq): (AnnotationSeq, AnnotationSeq) = (a, a)
+
+ def bToA(b: (AnnotationSeq, AnnotationSeq)): AnnotationSeq = {
+
+ val (in, out) = (mutable.LinkedHashSet() ++ b._1, mutable.LinkedHashSet() ++ b._2)
+
+ (in -- out).map {
+ case DeletedAnnotation(n, a) => DeletedAnnotation(s"$n+$name", a)
+ case a => DeletedAnnotation(name, a)
+ }.toSeq ++ b._2
+
+ }
+
+ def internalTransform(b: (AnnotationSeq, AnnotationSeq)): (AnnotationSeq, AnnotationSeq) = (b._1, p.transform(b._2))
+
+}
+
+object DeletedWrapper {
+
+ /** Wrap a [[firrtl.options.Phase Phase]] in a [[DeletedWrapper]]
+ * @param p a [[firrtl.options.Phase Phase]] to wrap
+ */
+ def apply(p: Phase): DeletedWrapper = new DeletedWrapper(p)
+
+}
diff --git a/src/main/scala/firrtl/passes/Inline.scala b/src/main/scala/firrtl/passes/Inline.scala
index dcee0ee2..0806563c 100644
--- a/src/main/scala/firrtl/passes/Inline.scala
+++ b/src/main/scala/firrtl/passes/Inline.scala
@@ -8,7 +8,7 @@ import firrtl.Mappers._
import firrtl.annotations._
import firrtl.analyses.InstanceGraph
import firrtl.stage.RunFirrtlTransformAnnotation
-import firrtl.options.RegisteredTransform
+import firrtl.options.{RegisteredTransform, ShellOption}
import scopt.OptionParser
// Datastructures
@@ -28,24 +28,22 @@ class InlineInstances extends Transform with RegisteredTransform {
def outputForm = LowForm
private [firrtl] val inlineDelim: String = "_"
- def addOptions(parser: OptionParser[AnnotationSeq]): Unit = parser
- .opt[Seq[String]]("inline")
- .abbr("fil")
- .valueName ("<circuit>[.<module>[.<instance>]][,..],")
- .action( (x, c) => {
- val newAnnotations = x.map { value =>
- value.split('.') match {
- case Array(circuit) =>
- InlineAnnotation(CircuitName(circuit))
- case Array(circuit, module) =>
- InlineAnnotation(ModuleName(module, CircuitName(circuit)))
- case Array(circuit, module, inst) =>
- InlineAnnotation(ComponentName(inst, ModuleName(module, CircuitName(circuit))))
- }
- }
- c ++ newAnnotations :+ RunFirrtlTransformAnnotation(new InlineInstances) } )
- .text(
- """Inline one or more module (comma separated, no spaces) module looks like "MyModule" or "MyModule.myinstance""")
+ val options = Seq(
+ new ShellOption[Seq[String]](
+ longOption = "inline",
+ toAnnotationSeq = (a: Seq[String]) => a.map { value =>
+ value.split('.') match {
+ case Array(circuit) =>
+ InlineAnnotation(CircuitName(circuit))
+ case Array(circuit, module) =>
+ InlineAnnotation(ModuleName(module, CircuitName(circuit)))
+ case Array(circuit, module, inst) =>
+ InlineAnnotation(ComponentName(inst, ModuleName(module, CircuitName(circuit))))
+ }
+ } :+ RunFirrtlTransformAnnotation(new InlineInstances),
+ helpText = "Inline selected modules",
+ shortOption = Some("fil"),
+ helpValueName = Some("<circuit>[.<module>[.<instance>]][,...]") ) )
private def collectAnns(circuit: Circuit, anns: Iterable[Annotation]): (Set[ModuleName], Set[ComponentName]) =
anns.foldLeft(Set.empty[ModuleName], Set.empty[ComponentName]) {
diff --git a/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala b/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
index de9f6c52..f95787bd 100644
--- a/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
+++ b/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
@@ -13,7 +13,7 @@ import ClockListUtils._
import Utils._
import memlib.AnalysisUtils._
import memlib._
-import firrtl.options.RegisteredTransform
+import firrtl.options.{RegisteredTransform, ShellOption}
import scopt.OptionParser
import firrtl.stage.RunFirrtlTransformAnnotation
@@ -60,14 +60,14 @@ class ClockListTransform extends Transform with RegisteredTransform {
def inputForm = LowForm
def outputForm = LowForm
- def addOptions(parser: OptionParser[AnnotationSeq]): Unit = parser
- .opt[String]("list-clocks")
- .abbr("clks")
- .valueName ("-c:<circuit>:-m:<module>:-o:<filename>")
- .action( (x, c) => c ++ Seq(passes.clocklist.ClockListAnnotation.parse(x),
- RunFirrtlTransformAnnotation(new ClockListTransform)) )
- .maxOccurs(1)
- .text("List which signal drives each clock of every descendent of specified module")
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "list-clocks",
+ toAnnotationSeq = (a: String) => Seq( passes.clocklist.ClockListAnnotation.parse(a),
+ RunFirrtlTransformAnnotation(new ClockListTransform) ),
+ helpText = "List which signal drives each clock of every descendent of specified modules",
+ shortOption = Some("clks"),
+ helpValueName = Some("-c:<circuit>:-m:<module>:-o:<filename>") ) )
def passSeq(top: String, writer: Writer): Seq[Pass] =
Seq(new ClockList(top, writer))
diff --git a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
index f524d60b..0602e4f1 100644
--- a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
+++ b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
@@ -8,7 +8,7 @@ import firrtl.ir._
import firrtl.Mappers._
import firrtl.PrimOps._
import firrtl.Utils.{one, zero, BoolType}
-import firrtl.options.HasScoptOptions
+import firrtl.options.{HasShellOptions, ShellOption}
import MemPortUtils.memPortField
import firrtl.passes.memlib.AnalysisUtils.{Connects, getConnects, getOrigin}
import WrappedExpression.weq
@@ -147,17 +147,16 @@ object InferReadWritePass extends Pass {
// Transform input: Middle Firrtl. Called after "HighFirrtlToMidleFirrtl"
// To use this transform, circuit name should be annotated with its TransId.
-class InferReadWrite extends Transform with SeqTransformBased with HasScoptOptions {
+class InferReadWrite extends Transform with SeqTransformBased with HasShellOptions {
def inputForm = MidForm
def outputForm = MidForm
- def addOptions(parser: OptionParser[AnnotationSeq]): Unit = parser
- .opt[Unit]("infer-rw")
- .abbr("firw")
- .valueName ("<circuit>")
- .action( (_, c) => Seq(InferReadWriteAnnotation, RunFirrtlTransformAnnotation(new InferReadWrite)) ++ c )
- .maxOccurs(1)
- .text("Enable readwrite port inference for the target circuit")
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "infer-rw",
+ toAnnotationSeq = (_: Unit) => Seq(InferReadWriteAnnotation, RunFirrtlTransformAnnotation(new InferReadWrite)),
+ helpText = "Enable read/write port inference for memories",
+ shortOption = Some("firw") ) )
def transforms = Seq(
InferReadWritePass,
diff --git a/src/main/scala/firrtl/passes/memlib/MemLibOptions.scala b/src/main/scala/firrtl/passes/memlib/MemLibOptions.scala
index 2f26e4e5..4076d5d6 100644
--- a/src/main/scala/firrtl/passes/memlib/MemLibOptions.scala
+++ b/src/main/scala/firrtl/passes/memlib/MemLibOptions.scala
@@ -3,13 +3,14 @@
package firrtl.passes.memlib
import firrtl._
-import firrtl.options.RegisteredLibrary
+import firrtl.options.{RegisteredLibrary, ShellOption}
import scopt.OptionParser
class MemLibOptions extends RegisteredLibrary {
val name: String = "MemLib Options"
- def addOptions(p: OptionParser[AnnotationSeq]): Unit =
- Seq( new InferReadWrite,
- new ReplSeqMem )
- .map(_.addOptions(p))
+
+ val options: Seq[ShellOption[_]] = Seq( new InferReadWrite,
+ new ReplSeqMem )
+ .flatMap(_.options)
+
}
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
index 32d83181..a9d0cc7c 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
@@ -6,7 +6,7 @@ package memlib
import firrtl._
import firrtl.ir._
import firrtl.annotations._
-import firrtl.options.HasScoptOptions
+import firrtl.options.{HasShellOptions, ShellOption}
import AnalysisUtils._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter}
@@ -102,18 +102,18 @@ class SimpleTransform(p: Pass, form: CircuitForm) extends Transform {
class SimpleMidTransform(p: Pass) extends SimpleTransform(p, MidForm)
// SimpleRun instead of PassBased because of the arguments to passSeq
-class ReplSeqMem extends Transform with HasScoptOptions {
+class ReplSeqMem extends Transform with HasShellOptions {
def inputForm = MidForm
def outputForm = MidForm
- def addOptions(parser: OptionParser[AnnotationSeq]): Unit = parser
- .opt[String]("repl-seq-mem")
- .abbr("frsq")
- .valueName ("-c:<circuit>:-i:<filename>:-o:<filename>")
- .action( (x, c) => Seq(passes.memlib.ReplSeqMemAnnotation.parse(x),
- RunFirrtlTransformAnnotation(new ReplSeqMem)) ++ c )
- .maxOccurs(1)
- .text("Replace sequential memories with blackboxes + configuration file")
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "repl-seq-mem",
+ toAnnotationSeq = (a: String) => Seq( passes.memlib.ReplSeqMemAnnotation.parse(a),
+ RunFirrtlTransformAnnotation(new ReplSeqMem) ),
+ helpText = "Blackbox and emit a configuration file for each sequential memory",
+ shortOption = Some("frsq"),
+ helpValueName = Some("-c:<circuit>:-i:<file>:-o:<file>") ) )
def transforms(inConfigFile: Option[YamlFileReader], outConfigFile: ConfWriter): Seq[Transform] =
Seq(new SimpleMidTransform(Legalize),
diff --git a/src/main/scala/firrtl/stage/FirrtlAnnotations.scala b/src/main/scala/firrtl/stage/FirrtlAnnotations.scala
index 600e825b..ed5415f6 100644
--- a/src/main/scala/firrtl/stage/FirrtlAnnotations.scala
+++ b/src/main/scala/firrtl/stage/FirrtlAnnotations.scala
@@ -5,7 +5,7 @@ package firrtl.stage
import firrtl._
import firrtl.ir.Circuit
import firrtl.annotations.{Annotation, NoTargetAnnotation}
-import firrtl.options.{HasScoptOptions, OptionsException}
+import firrtl.options.{HasShellOptions, OptionsException, ShellOption}
import scopt.OptionParser
@@ -49,13 +49,16 @@ case class FirrtlFileAnnotation(file: String) extends NoTargetAnnotation with Ci
}
-object FirrtlFileAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("input-file")
- .abbr("i")
- .valueName ("<firrtl-source>")
- .action( (x, c) => FirrtlFileAnnotation(x) +: c )
- .unbounded()
- .text("use this to override the default input file name, default is empty")
+object FirrtlFileAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "input-file",
+ toAnnotationSeq = a => Seq(FirrtlFileAnnotation(a)),
+ helpText = "An input FIRRTL file",
+ shortOption = Some("i"),
+ helpValueName = Some("<file>") ) )
+
}
/** An explicit output file the emitter will write to
@@ -64,13 +67,16 @@ object FirrtlFileAnnotation extends HasScoptOptions {
*/
case class OutputFileAnnotation(file: String) extends NoTargetAnnotation with FirrtlOption
-object OutputFileAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("output-file")
- .abbr("o")
- .valueName("<output>")
- .action( (x, c) => OutputFileAnnotation(x) +: c )
- .unbounded()
- .text("use this to override the default output file name, default is empty")
+object OutputFileAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "output-file",
+ toAnnotationSeq = a => Seq(OutputFileAnnotation(a)),
+ helpText = "The output FIRRTL file",
+ shortOption = Some("o"),
+ helpValueName = Some("<file>") ) )
+
}
/** Sets the info mode style
@@ -97,12 +103,15 @@ case class InfoModeAnnotation(modeName: String = "use") extends NoTargetAnnotati
}
}
-object InfoModeAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("info-mode")
- .valueName ("<ignore|use|gen|append>")
- .action( (x, c) => InfoModeAnnotation(x) +: c )
- .unbounded()
- .text(s"specifies the source info handling, default is ${apply().modeName}")
+object InfoModeAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "info-mode",
+ toAnnotationSeq = a => Seq(InfoModeAnnotation(a)),
+ helpText = s"Source file info handling mode (default: ${apply().modeName})",
+ shortOption = Some("<ignore|use|gen|append>") ) )
+
}
/** Holds a [[scala.Predef.String String]] containing FIRRTL source to read as input
@@ -116,22 +125,25 @@ case class FirrtlSourceAnnotation(source: String) extends NoTargetAnnotation wit
}
-object FirrtlSourceAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("firrtl-source")
- .valueName ("A FIRRTL string")
- .action( (x, c) => FirrtlSourceAnnotation(x) +: c )
- .unbounded()
- .text(s"A FIRRTL circuit as a string")
+object FirrtlSourceAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "firrtl-source",
+ toAnnotationSeq = a => Seq(FirrtlSourceAnnotation(a)),
+ helpText = "An input FIRRTL circuit string",
+ shortOption = Some("<string>") ) )
+
}
-/** Holds a [[Compiler]] that should be run
+/** helpValueName a [[Compiler]] that should be run
* - set stringly with `-X/--compiler`
* - If unset, a [[CompilerAnnotation]] with the default [[VerilogCompiler]]
* @param compiler compiler name
*/
case class CompilerAnnotation(compiler: Compiler = new VerilogCompiler()) extends NoTargetAnnotation with FirrtlOption
-object CompilerAnnotation extends HasScoptOptions {
+object CompilerAnnotation extends HasShellOptions {
private [firrtl] def apply(compilerName: String): CompilerAnnotation = {
val c = compilerName match {
@@ -147,12 +159,14 @@ object CompilerAnnotation extends HasScoptOptions {
CompilerAnnotation(c)
}
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("compiler")
- .abbr("X")
- .valueName ("<none|high|middle|low|verilog|mverilog|sverilog>")
- .action{ (x, c) => CompilerAnnotation(x) +: c }
- .unbounded()
- .text(s"compiler to use, default is 'verilog'")
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "compiler",
+ toAnnotationSeq = a => Seq(CompilerAnnotation(a)),
+ helpText = "The FIRRTL compiler to use (default: verilog)",
+ shortOption = Some("X"),
+ helpValueName = Some("<none|high|middle|low|verilog|mverilog|sverilog>") ) )
+
}
/** Holds the unambiguous class name of a [[Transform]] to run
@@ -162,27 +176,26 @@ object CompilerAnnotation extends HasScoptOptions {
*/
case class RunFirrtlTransformAnnotation(transform: Transform) extends NoTargetAnnotation
-object RunFirrtlTransformAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[Seq[String]]("custom-transforms")
- .abbr("fct")
- .valueName ("<package>.<class>")
- .validate( x => {
- x.map(txName =>
- try { Class.forName(txName).asInstanceOf[Class[_ <: Transform]].newInstance() }
- catch {
- case e: ClassNotFoundException => throw new OptionsException(
- s"Unable to locate custom transform $txName (did you misspell it?)", e)
- case e: InstantiationException => throw new OptionsException(
- s"Unable to create instance of Transform $txName (is this an anonymous class?)", e)
- case e: Throwable => throw new OptionsException(
- s"Unknown error when instantiating class $txName", e) } )
- p.success } )
- .action( (x, c) =>
- x.map(txName =>
- RunFirrtlTransformAnnotation(Class.forName(txName).asInstanceOf[Class[_ <: Transform]].newInstance()))
- .reverse ++ c )
- .unbounded()
- .text("runs these custom transforms during compilation.")
+object RunFirrtlTransformAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[Seq[String]](
+ longOption = "custom-transforms",
+ toAnnotationSeq = _.map(txName =>
+ try {
+ val tx = Class.forName(txName).asInstanceOf[Class[_ <: Transform]].newInstance()
+ RunFirrtlTransformAnnotation(tx)
+ } catch {
+ case e: ClassNotFoundException => throw new OptionsException(
+ s"Unable to locate custom transform $txName (did you misspell it?)", e)
+ case e: InstantiationException => throw new OptionsException(
+ s"Unable to create instance of Transform $txName (is this an anonymous class?)", e)
+ case e: Throwable => throw new OptionsException(
+ s"Unknown error when instantiating class $txName", e) }),
+ helpText = "Run these transforms during compilation",
+ shortOption = Some("fct"),
+ helpValueName = Some("<package>.<class>") ) )
+
}
/** Holds a FIRRTL [[firrtl.ir.Circuit Circuit]]
diff --git a/src/main/scala/firrtl/stage/FirrtlStage.scala b/src/main/scala/firrtl/stage/FirrtlStage.scala
index e4620913..5d121322 100644
--- a/src/main/scala/firrtl/stage/FirrtlStage.scala
+++ b/src/main/scala/firrtl/stage/FirrtlStage.scala
@@ -3,7 +3,8 @@
package firrtl.stage
import firrtl.{AnnotationSeq, CustomTransformException, FIRRTLException, Utils}
-import firrtl.options.{Phase, PhaseException, Shell, Stage, StageMain, OptionsException}
+import firrtl.options.{Stage, Phase, PhaseException, Shell, OptionsException, StageMain}
+import firrtl.options.phases.DeletedWrapper
import firrtl.passes.{PassException, PassExceptions}
import scala.util.control.ControlThrowable
@@ -13,18 +14,18 @@ import java.io.PrintWriter
class FirrtlStage extends Stage {
val shell: Shell = new Shell("firrtl") with FirrtlCli
- private val phases: Seq[Phase] = Seq(
- new firrtl.stage.phases.AddDefaults,
- new firrtl.stage.phases.AddImplicitEmitter,
- new firrtl.stage.phases.Checks,
- new firrtl.stage.phases.AddCircuit,
- new firrtl.stage.phases.AddImplicitOutputFile,
- new firrtl.stage.phases.Compiler,
- new firrtl.stage.phases.WriteEmitted
- )
+ private val phases: Seq[Phase] =
+ Seq( new firrtl.stage.phases.AddDefaults,
+ new firrtl.stage.phases.AddImplicitEmitter,
+ new firrtl.stage.phases.Checks,
+ new firrtl.stage.phases.AddCircuit,
+ new firrtl.stage.phases.AddImplicitOutputFile,
+ new firrtl.stage.phases.Compiler,
+ new firrtl.stage.phases.WriteEmitted )
+ .map(DeletedWrapper(_))
def run(annotations: AnnotationSeq): AnnotationSeq = try {
- phases.foldLeft(annotations)((a, f) => f.runTransform(a))
+ phases.foldLeft(annotations)((a, f) => f.transform(a))
} catch {
/* Rethrow the exceptions which are expected or due to the runtime environment (out of memory, stack overflow, etc.).
* Any UNEXPECTED exceptions should be treated as internal errors. */
diff --git a/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala b/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala
index 310e0bd4..cb6a135d 100644
--- a/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala
+++ b/src/main/scala/firrtl/stage/phases/DriverCompatibility.scala
@@ -7,8 +7,8 @@ import firrtl.stage._
import firrtl.{AnnotationSeq, EmitAllModulesAnnotation, EmitCircuitAnnotation, FirrtlExecutionResult, Parser}
import firrtl.annotations.NoTargetAnnotation
import firrtl.proto.FromProto
-import firrtl.options.{HasScoptOptions, InputAnnotationFileAnnotation, OptionsException, Phase, StageOptions,
- StageUtils}
+import firrtl.options.{HasShellOptions, InputAnnotationFileAnnotation, OptionsException, Phase, ShellOption,
+ StageOptions, StageUtils}
import firrtl.options.Viewer
import scopt.OptionParser
@@ -49,7 +49,8 @@ object DriverCompatibility {
@deprecated(""""top-name" is deprecated as part of the Stage/Phase refactor. Use explicit input/output files.""", "1.2")
case class TopNameAnnotation(topName: String) extends NoTargetAnnotation
- object TopNameAnnotation extends HasScoptOptions {
+ object TopNameAnnotation {
+
def addOptions(p: OptionParser[AnnotationSeq]): Unit = p
.opt[Unit]("top-name")
.abbr("tn")
diff --git a/src/main/scala/firrtl/transforms/CheckCombLoops.scala b/src/main/scala/firrtl/transforms/CheckCombLoops.scala
index 0a9ec0e3..17e1569b 100644
--- a/src/main/scala/firrtl/transforms/CheckCombLoops.scala
+++ b/src/main/scala/firrtl/transforms/CheckCombLoops.scala
@@ -17,7 +17,7 @@ import firrtl.annotations._
import firrtl.Utils.throwInternalError
import firrtl.graph.{MutableDiGraph,DiGraph}
import firrtl.analyses.InstanceGraph
-import firrtl.options.RegisteredTransform
+import firrtl.options.{RegisteredTransform, ShellOption}
import scopt.OptionParser
object CheckCombLoops {
@@ -69,11 +69,11 @@ class CheckCombLoops extends Transform with RegisteredTransform {
import CheckCombLoops._
- def addOptions(parser: OptionParser[AnnotationSeq]): Unit = parser
- .opt[Unit]("no-check-comb-loops")
- .action( (x, c) => c :+ DontCheckCombLoopsAnnotation )
- .maxOccurs(1)
- .text("Do NOT check for combinational loops (not recommended)")
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "no-check-comb-loops",
+ toAnnotationSeq = (_: Unit) => Seq(DontCheckCombLoopsAnnotation),
+ helpText = "Disable combinational loop checking" ) )
/*
* A case class that represents a net in the circuit. This is
diff --git a/src/main/scala/firrtl/transforms/DeadCodeElimination.scala b/src/main/scala/firrtl/transforms/DeadCodeElimination.scala
index deb7299d..0c357267 100644
--- a/src/main/scala/firrtl/transforms/DeadCodeElimination.scala
+++ b/src/main/scala/firrtl/transforms/DeadCodeElimination.scala
@@ -11,7 +11,7 @@ import firrtl.Mappers._
import firrtl.WrappedExpression._
import firrtl.Utils.{throwInternalError, toWrappedExpression, kind}
import firrtl.MemoizedHash._
-import firrtl.options.RegisteredTransform
+import firrtl.options.{RegisteredTransform, ShellOption}
import scopt.OptionParser
import collection.mutable
@@ -36,11 +36,11 @@ class DeadCodeElimination extends Transform with ResolvedAnnotationPaths with Re
def inputForm = LowForm
def outputForm = LowForm
- def addOptions(parser: OptionParser[AnnotationSeq]): Unit = parser
- .opt[Unit]("no-dce")
- .action( (x, c) => c :+ NoDCEAnnotation )
- .maxOccurs(1)
- .text("Do NOT run dead code elimination")
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "no-dce",
+ toAnnotationSeq = (_: Unit) => Seq(NoDCEAnnotation),
+ helpText = "Disable dead code elimination" ) )
/** Based on LogicNode ins CheckCombLoops, currently kind of faking it */
private type LogicNode = MemoizedHash[WrappedExpression]
diff --git a/src/main/scala/logger/Logger.scala b/src/main/scala/logger/Logger.scala
index 1cf7d7ee..00c29b1a 100644
--- a/src/main/scala/logger/Logger.scala
+++ b/src/main/scala/logger/Logger.scala
@@ -363,9 +363,9 @@ object Logger {
* @param inputAnnotations annotation sequence containing logger options
*/
def setOptions(inputAnnotations: AnnotationSeq): Unit = {
- val annotations = Seq( AddDefaults,
- Checks )
- .foldLeft(inputAnnotations)((a, p) => p.runTransform(a))
+ val annotations =
+ Seq( AddDefaults, Checks )
+ .foldLeft(inputAnnotations)((a, p) => p.transform(a))
val lopts = view[LoggerOptions](annotations)
state.globalLevel = (state.globalLevel, lopts.globalLogLevel) match {
diff --git a/src/main/scala/logger/LoggerAnnotations.scala b/src/main/scala/logger/LoggerAnnotations.scala
index 2811cc6c..204fc4ab 100644
--- a/src/main/scala/logger/LoggerAnnotations.scala
+++ b/src/main/scala/logger/LoggerAnnotations.scala
@@ -4,7 +4,7 @@ package logger
import firrtl.AnnotationSeq
import firrtl.annotations.{Annotation, NoTargetAnnotation}
-import firrtl.options.{HasScoptOptions, StageUtils}
+import firrtl.options.{HasShellOptions, ShellOption, StageUtils}
import scopt.OptionParser
@@ -18,17 +18,16 @@ sealed trait LoggerOption { this: Annotation => }
*/
case class LogLevelAnnotation(globalLogLevel: LogLevel.Value = LogLevel.None) extends NoTargetAnnotation with LoggerOption
-object LogLevelAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[String]("log-level")
- .abbr("ll")
- .valueName("<Error|Warn|Info|Debug|Trace>")
- .action( (x, c) => LogLevelAnnotation(LogLevel(x)) +: c )
- .validate{ x =>
- lazy val msg = s"$x bad value must be one of error|warn|info|debug|trace"
- if (Array("error", "warn", "info", "debug", "trace").contains(x.toLowerCase)) { p.success }
- else { p.failure(msg) }}
- .unbounded()
- .text(s"Sets the verbosity level of logging, default is ${new LoggerOptions().globalLogLevel}")
+object LogLevelAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "log-level",
+ toAnnotationSeq = (a: String) => Seq(LogLevelAnnotation(LogLevel(a))),
+ helpText = s"Set global logging verbosity (default: ${new LoggerOptions().globalLogLevel}",
+ shortOption = Some("ll"),
+ helpValueName = Some("{error|warn|info|debug|trace}") ) )
+
}
/** Describes a mapping of a class to a specific log level
@@ -38,16 +37,19 @@ object LogLevelAnnotation extends HasScoptOptions {
*/
case class ClassLogLevelAnnotation(className: String, level: LogLevel.Value) extends NoTargetAnnotation with LoggerOption
-object ClassLogLevelAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[Seq[String]]("class-log-level")
- .abbr("cll")
- .valueName("<FullClassName:[Error|Warn|Info|Debug|Trace]>[,...]")
- .action( (x, c) => (x.map { y =>
- val className :: levelName :: _ = y.split(":").toList
- val level = LogLevel(levelName)
- ClassLogLevelAnnotation(className, level) }) ++ c )
- .unbounded()
- .text(s"This defines per-class verbosity of logging")
+object ClassLogLevelAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[Seq[String]](
+ longOption = "class-log-level",
+ toAnnotationSeq = (a: Seq[String]) => a.map { aa =>
+ val className :: levelName :: _ = aa.split(":").toList
+ val level = LogLevel(levelName)
+ ClassLogLevelAnnotation(className, level) },
+ helpText = "Set per-class logging verbosity",
+ shortOption = Some("cll"),
+ helpValueName = Some("<FullClassName:{error|warn|info|debug|trace}>...") ) )
+
}
/** Enables logging to a file (as opposed to STDOUT)
@@ -56,22 +58,27 @@ object ClassLogLevelAnnotation extends HasScoptOptions {
*/
case class LogFileAnnotation(file: Option[String]) extends NoTargetAnnotation with LoggerOption
-object LogFileAnnotation extends HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = {
- p.opt[String]("log-file")
- .action( (x, c) => LogFileAnnotation(Some(x)) +: c )
- .unbounded()
- .text(s"log to the specified file")
- }
+object LogFileAnnotation extends HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[String](
+ longOption = "log-file",
+ toAnnotationSeq = (a: String) => Seq(LogFileAnnotation(Some(a))),
+ helpText = "Log to a file instead of STDOUT",
+ helpValueName = Some("<file>") ) )
+
}
/** Enables class names in log output
* - enabled with `-lcn/--log-class-names`
*/
-case object LogClassNamesAnnotation extends NoTargetAnnotation with LoggerOption with HasScoptOptions {
- def addOptions(p: OptionParser[AnnotationSeq]): Unit = p.opt[Unit]("log-class-names")
- .abbr("lcn")
- .action( (x, c) => LogClassNamesAnnotation +: c )
- .unbounded()
- .text(s"shows class names and log level in logging output, useful for target --class-log-level")
+case object LogClassNamesAnnotation extends NoTargetAnnotation with LoggerOption with HasShellOptions {
+
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "log-class-names",
+ toAnnotationSeq = (a: Unit) => Seq(LogClassNamesAnnotation),
+ helpText = "Show class names and log level in logging output",
+ shortOption = Some("lcn") ) )
+
}
diff --git a/src/test/scala/firrtlTests/options/RegistrationSpec.scala b/src/test/scala/firrtlTests/options/RegistrationSpec.scala
index c060341d..43d71b6d 100644
--- a/src/test/scala/firrtlTests/options/RegistrationSpec.scala
+++ b/src/test/scala/firrtlTests/options/RegistrationSpec.scala
@@ -6,7 +6,7 @@ import org.scalatest.{FlatSpec, Matchers}
import scopt.OptionParser
import java.util.ServiceLoader
-import firrtl.options.{RegisteredTransform, RegisteredLibrary}
+import firrtl.options.{RegisteredTransform, RegisteredLibrary, ShellOption}
import firrtl.passes.Pass
import firrtl.ir.Circuit
import firrtl.annotations.NoTargetAnnotation
@@ -16,16 +16,23 @@ case object HelloAnnotation extends NoTargetAnnotation
class FooTransform extends Pass with RegisteredTransform {
def run(c: Circuit): Circuit = c
- def addOptions(p: OptionParser[AnnotationSeq]): Unit =
- p.opt[Unit]("hello")
- .action( (_, c) => HelloAnnotation +: c )
+
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "hello",
+ toAnnotationSeq = _ => Seq(HelloAnnotation),
+ helpText = "Hello option") )
+
}
class BarLibrary extends RegisteredLibrary {
def name: String = "Bar"
- def addOptions(p: OptionParser[AnnotationSeq]): Unit =
- p.opt[Unit]("world")
- .action( (_, c) => HelloAnnotation +: c )
+
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "world",
+ toAnnotationSeq = _ => Seq(HelloAnnotation),
+ helpText = "World option") )
}
class RegistrationSpec extends FlatSpec with Matchers {
diff --git a/src/test/scala/firrtlTests/options/phases/ChecksSpec.scala b/src/test/scala/firrtlTests/options/phases/ChecksSpec.scala
index e04ba554..b988f838 100644
--- a/src/test/scala/firrtlTests/options/phases/ChecksSpec.scala
+++ b/src/test/scala/firrtlTests/options/phases/ChecksSpec.scala
@@ -13,14 +13,14 @@ class ChecksSpec extends FlatSpec with Matchers {
val targetDir = TargetDirAnnotation("foo")
val annoOut = OutputAnnotationFileAnnotation("bar")
+ class Fixture { val phase: Phase = new Checks }
+
/* A minimum annotation Seq that will pass [[Checks]] */
val min = Seq(targetDir)
def checkExceptionMessage(phase: Phase, annotations: AnnotationSeq, messageStart: String): Unit =
intercept[OptionsException]{ phase.transform(annotations) }.getMessage should startWith(messageStart)
- class Fixture { val phase: Phase = new Checks }
-
behavior of classOf[Checks].toString
it should "enforce exactly one TargetDirAnnotation" in new Fixture {
diff --git a/src/test/scala/firrtlTests/options/phases/GetIncludesSpec.scala b/src/test/scala/firrtlTests/options/phases/GetIncludesSpec.scala
index 5b07d0e0..1007ca8c 100644
--- a/src/test/scala/firrtlTests/options/phases/GetIncludesSpec.scala
+++ b/src/test/scala/firrtlTests/options/phases/GetIncludesSpec.scala
@@ -21,7 +21,6 @@ case object E extends NoTargetAnnotation
class GetIncludesSpec extends FlatSpec with Matchers with BackendCompilationUtilities with firrtlTests.Utils {
-
val dir = new File("test_run_dir/GetIncludesSpec")
dir.mkdirs()