diff options
| author | Adam Izraelevitz | 2016-05-02 14:59:51 -0700 |
|---|---|---|
| committer | jackkoenig | 2016-05-12 22:42:06 -0700 |
| commit | f07baed2bc46e107250c317f290af48747a98322 (patch) | |
| tree | a63c5d2477eabccab85dc6780f289fc24cbcad5c /src/main/scala/firrtl/Driver.scala | |
| parent | 0ee659e85c7fe46c2678a49866ef1eca8f4a2c65 (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.scala | 113 |
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.") } } } |
