aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/Driver.scala
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-05-02 14:59:51 -0700
committerjackkoenig2016-05-12 22:42:06 -0700
commitf07baed2bc46e107250c317f290af48747a98322 (patch)
treea63c5d2477eabccab85dc6780f289fc24cbcad5c /src/main/scala/firrtl/Driver.scala
parent0ee659e85c7fe46c2678a49866ef1eca8f4a2c65 (diff)
Restructured Compiler to use Transforms. Added an InlineInstance pass.
Transforms are new unit of modularity within the compiler.
Diffstat (limited to 'src/main/scala/firrtl/Driver.scala')
-rw-r--r--src/main/scala/firrtl/Driver.scala113
1 files changed, 69 insertions, 44 deletions
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala
index 587be24c..684bc569 100644
--- a/src/main/scala/firrtl/Driver.scala
+++ b/src/main/scala/firrtl/Driver.scala
@@ -24,87 +24,112 @@ ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
*/
-package firrtl
-import java.io._
-import java.nio.file.{Paths, Files}
+package firrtl
+import java.io.{PrintWriter, Writer, File}
import scala.io.Source
-import scala.sys.process._
-
-import com.typesafe.scalalogging.LazyLogging
+import scala.collection.mutable
import Utils._
import Parser.{InfoMode, IgnoreInfo, UseInfo, GenInfo, AppendInfo}
-object Driver extends LazyLogging {
+object Driver {
private val usage = """
Usage: sbt "run-main firrtl.Driver -i <input_file> -o <output_file> -X <compiler>"
firrtl -i <input_file> -o <output_file> -X <compiler> [options]
Options:
- -X <compiler> Specify the target language
- Currently supported: verilog firrtl
- --info-mode=<mode> Specify Info Mode
+ -X <compiler> Specify the target compiler
+ Currently supported: high low verilog
+ --info-mode <mode> Specify Info Mode
Supported modes: ignore, use, gen, append
"""
- private val defaultOptions = Map[Symbol, Any]().withDefaultValue(false)
- def compile(input: String, output: String, compiler: Compiler, infoMode: InfoMode = IgnoreInfo)
- {
+ // Compiles circuit. First parses a circuit from an input file,
+ // executes all compiler passes, and writes result to an output
+ // file.
+ def compile(
+ input: String,
+ output: String,
+ compiler: Compiler,
+ infoMode: InfoMode = IgnoreInfo,
+ annotations: Seq[CircuitAnnotation] = Seq.empty) = {
val parsedInput = Parser.parse(Source.fromFile(input).getLines, infoMode)
val writerOutput = new PrintWriter(new File(output))
- compiler.run(parsedInput, writerOutput)
+ compiler.compile(parsedInput, annotations, writerOutput)
writerOutput.close
}
- def main(args: Array[String])
- {
+ // Arguments specify the compiler, input file, and output file
+ def main(args: Array[String]) = {
val arglist = args.toList
- type OptionMap = Map[Symbol, Any]
+ sealed trait CompilerOption
+ case object InputFileName extends CompilerOption
+ case object OutputFileName extends CompilerOption
+ case object CompilerName extends CompilerOption
+ case object InfoModeOption extends CompilerOption
+ val defaultOptions = Map[CompilerOption, String]()
+
+ // Inline Annotation datastructure/function
+ val inlineAnnotations = mutable.HashMap[Named,Annotation]()
+ def handleInlineOption(value: String): Unit =
+ value.split('.') match {
+ case Array(module) =>
+ inlineAnnotations(ModuleName(module)) = TagAnnotation
+ case Array(module, inst) =>
+ inlineAnnotations(ComponentName(inst,ModuleName(module))) = TagAnnotation
+ case _ => throw new Exception(s"Bad inline instance/module name: $value")
+ }
+
+ type OptionMap = Map[CompilerOption, String]
def nextOption(map: OptionMap, list: List[String]): OptionMap = {
list match {
case Nil => map
+ case "--inline" :: value :: tail =>
+ handleInlineOption(value)
+ nextOption(map, tail)
case "-X" :: value :: tail =>
- nextOption(map ++ Map('compiler -> value), tail)
+ nextOption(map + (CompilerName -> value), tail)
case "-i" :: value :: tail =>
- nextOption(map ++ Map('input -> value), tail)
+ nextOption(map + (InputFileName -> value), tail)
case "-o" :: value :: tail =>
- nextOption(map ++ Map('output -> value), tail)
+ nextOption(map + (OutputFileName -> value), tail)
case "--info-mode" :: value :: tail =>
- nextOption(map ++ Map('infoMode -> value), tail)
- case ("-h" | "--help") :: tail =>
- nextOption(map ++ Map('help -> true), tail)
+ nextOption(map + (InfoModeOption -> value), tail)
+ case ("-h" | "--help") :: tail => { println(usage); sys.exit(0) }
case option :: tail =>
throw new Exception("Unknown option " + option)
}
}
+
val options = nextOption(defaultOptions, arglist)
- if (options('help) == true) {
- println(usage)
- System.exit(0)
- }
+ // Get input circuit/output filenames
+ val input = options.getOrElse(InputFileName, throw new Exception("No input file provided!" + usage))
+ val output = options.getOrElse(OutputFileName, throw new Exception("No output file provided!" + usage))
- val input = options('input) match {
- case s: String => s
- case false => throw new Exception("No input file provided!" + usage)
- }
- val output = options('output) match {
- case s: String => s
- case false => throw new Exception("No output file provided!" + usage)
- }
- val infoMode = options('infoMode) match {
- case ("use" | false) => UseInfo
- case "ignore" => IgnoreInfo
- case "gen" => GenInfo(input)
- case "append" => AppendInfo(input)
+ val infoMode = options.get(InfoModeOption) match {
+ case (Some("use") | None) => UseInfo
+ case Some("ignore") => IgnoreInfo
+ case Some("gen") => GenInfo(input)
+ case Some("append") => AppendInfo(input)
+ case Some(other) => throw new Exception("Unknown info mode option: " + other)
}
- options('compiler) match {
- case "verilog" => compile(input, output, VerilogCompiler, infoMode)
- case "firrtl" => compile(input, output, FIRRTLCompiler, infoMode)
- case other => throw new Exception("Invalid compiler! " + other)
+ // Construct all Circuit Annotations
+ val inlineCA =
+ if (inlineAnnotations.isEmpty) Seq.empty
+ else Seq(StickyCircuitAnnotation(passes.InlineCAKind, inlineAnnotations.toMap))
+ val allAnnotations = inlineCA // other annotations will be added here
+
+ // Execute selected compiler - error if not recognized compiler
+ options.get(CompilerName) match {
+ case Some("high") => compile(input, output, new HighFirrtlCompiler(), infoMode, allAnnotations)
+ case Some("low") => compile(input, output, new LowFirrtlCompiler(), infoMode, allAnnotations)
+ case Some("verilog") => compile(input, output, new VerilogCompiler(), infoMode, allAnnotations)
+ case Some(other) => throw new Exception("Unknown compiler option: " + other)
+ case None => throw new Exception("No specified compiler option.")
}
}
}