diff options
Diffstat (limited to 'src/main/scala')
| -rw-r--r-- | src/main/scala/firrtl/Compiler.scala | 87 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Driver.scala | 46 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Emitter.scala | 207 | ||||
| -rw-r--r-- | src/main/scala/firrtl/ExecutionOptionsManager.scala | 82 | ||||
| -rw-r--r-- | src/main/scala/firrtl/LoweringCompilers.scala | 10 | ||||
| -rw-r--r-- | src/main/scala/firrtl/annotations/Named.scala | 6 |
6 files changed, 376 insertions, 62 deletions
diff --git a/src/main/scala/firrtl/Compiler.scala b/src/main/scala/firrtl/Compiler.scala index 808fa435..6251fc5c 100644 --- a/src/main/scala/firrtl/Compiler.scala +++ b/src/main/scala/firrtl/Compiler.scala @@ -8,6 +8,7 @@ import annotations._ import firrtl.ir.Circuit import passes.Pass +import Utils.throwInternalError /** * RenameMap maps old names to modified names. Generated by transformations @@ -33,10 +34,28 @@ case class AnnotationMap(annotations: Seq[Annotation]) { * Generally only a return value from [[Transform]]s */ case class CircuitState( - circuit: Circuit, - form: CircuitForm, - annotations: Option[AnnotationMap] = None, - renames: Option[RenameMap] = None) + circuit: Circuit, + form: CircuitForm, + annotations: Option[AnnotationMap] = None, + renames: Option[RenameMap] = None) { + + /** Helper for getting just an emitted circuit */ + def emittedCircuitOption: Option[EmittedCircuit] = + emittedComponents collectFirst { case x: EmittedCircuit => x } + /** Helper for getting an [[EmittedCircuit]] when it is known to exist */ + def getEmittedCircuit: EmittedCircuit = emittedCircuitOption match { + case Some(emittedCircuit) => emittedCircuit + case None => throw new FIRRTLException("No EmittedCircuit found! Check Emitter Annotations") + } + /** Helper function for extracting emitted components from annotations */ + def emittedComponents: Seq[EmittedComponent] = { + val emittedOpt = annotations map (_.annotations collect { + case EmittedCircuitAnnotation(x) => x + case EmittedModuleAnnotation(x) => x + }) + emittedOpt.getOrElse(Seq.empty) + } +} /** Current form of the Firrtl Circuit * @@ -137,10 +156,9 @@ abstract class PassBasedTransform extends Transform with PassBased { } } -/** Similar to a Transform except that it writes to a Writer instead of returning a - * CircuitState - */ -abstract class Emitter { +/** Defines old API for Emission. Deprecated */ +trait Emitter extends Transform { + @deprecated("Use emission annotations instead", "firrtl 1.0") def emit(state: CircuitState, writer: Writer): Unit } @@ -157,12 +175,13 @@ object CompilerUtils { Seq.empty } else { inputForm match { - case ChirrtlForm => Seq(new ChirrtlToHighFirrtl) ++ getLoweringTransforms(HighForm, outputForm) + case ChirrtlForm => + Seq(new ChirrtlToHighFirrtl) ++ getLoweringTransforms(HighForm, outputForm) case HighForm => Seq(new IRToWorkingIR, new ResolveAndCheck, new transforms.DedupModules, new HighFirrtlToMiddleFirrtl) ++ getLoweringTransforms(MidForm, outputForm) case MidForm => Seq(new MiddleFirrtlToLowFirrtl) ++ getLoweringTransforms(LowForm, outputForm) - case LowForm => error("Internal Error! This shouldn't be possible") // should be caught by if above + case LowForm => throwInternalError // should be caught by if above } } } @@ -212,7 +231,9 @@ object CompilerUtils { } trait Compiler { + // Emitter is still somewhat special because we want to make sure it is run last def emitter: Emitter + /** The sequence of transforms this compiler will execute * @note The inputForm of a given transform must be higher than or equal to the ouputForm of the * preceding transform. See [[CircuitForm]] @@ -242,10 +263,52 @@ trait Compiler { * @param customTransforms Any custom [[Transform]]s that will be inserted * into the compilation process by [[CompilerUtils.mergeTransforms]] */ + @deprecated("Please use compileAndEmit or other compile method instead", "firrtl 1.0") def compile(state: CircuitState, writer: Writer, customTransforms: Seq[Transform] = Seq.empty): CircuitState = { - val allTransforms = CompilerUtils.mergeTransforms(transforms, customTransforms) + val finalState = compileAndEmit(state, customTransforms) + finalState.emittedCircuitOption match { + case Some(emitted) => writer.write(emitted.value) + case _ => throwInternalError + } + finalState + } + + /** Perform compilation and emit the whole Circuit + * + * This is intended as a convenience method wrapping up Annotation creation for the common case. + * It creates a [[EmitCircuitAnnotation]] that will be consumed by this Transform's emitter. The + * [[EmittedCircuit]] can be extracted from the returned [[CircuitState]] via + * [[CircuitState.emittedCircuitOption]] + * + * @param state The Firrtl AST to compile + * @param customTransforms Any custom [[Transform]]s that will be inserted + * into the compilation process by [[CompilerUtils.mergeTransforms]] + * @return result of compilation with emitted circuit annotated + */ + def compileAndEmit(state: CircuitState, + customTransforms: Seq[Transform] = Seq.empty): CircuitState = { + val emitAnno = EmitCircuitAnnotation(emitter.getClass) + // TODO This is ridiculous. Fix Annotations + val annotations = state.annotations.map(_.annotations).getOrElse(Seq.empty) + val annotationMap = AnnotationMap(annotations :+ emitAnno) + + // Run compiler + compile(state.copy(annotations = Some(annotationMap)), customTransforms) + } + + /** Perform compilation + * + * Emission will only be performed if [[EmitAnnotation]]s are present + * + * @param state The Firrtl AST to compile + * @param customTransforms Any custom [[Transform]]s that will be inserted into the compilation + * process by [[CompilerUtils.mergeTransforms]] + * @return result of compilation + */ + def compile(state: CircuitState, customTransforms: Seq[Transform]): CircuitState = { + val allTransforms = CompilerUtils.mergeTransforms(transforms, customTransforms) :+ emitter val finalState = allTransforms.foldLeft(state) { (in, xform) => val result = Utils.time(s"***${xform.name}***") { xform.execute(in) } @@ -273,8 +336,6 @@ trait Compiler { val newAnnotations = AnnotationMap(remappedAnnotations ++ resultAnnotations) CircuitState(result.circuit, result.form, Some(newAnnotations)) } - - emitter.emit(finalState, writer) finalState } } diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala index 0fdfa768..f321ad16 100644 --- a/src/main/scala/firrtl/Driver.scala +++ b/src/main/scala/firrtl/Driver.scala @@ -13,6 +13,7 @@ import Parser.{IgnoreInfo, InfoMode} import annotations._ import firrtl.annotations.AnnotationYamlProtocol._ import firrtl.transforms.{BlackBoxSourceHelper, BlackBoxTargetDir} +import Utils.throwInternalError /** @@ -41,6 +42,7 @@ object Driver { // Compiles circuit. First parses a circuit from an input file, // executes all compiler passes, and writes result to an output // file. + @deprecated("Please use execute", "firrtl 1.0") def compile( input: String, output: String, @@ -155,20 +157,44 @@ object Driver { loadAnnotations(optionsManager) val parsedInput = Parser.parse(firrtlSource, firrtlConfig.infoMode) - val outputBuffer = new java.io.CharArrayWriter - firrtlConfig.compiler.compile( - CircuitState(parsedInput, ChirrtlForm, Some(AnnotationMap(firrtlConfig.annotations))), - outputBuffer, + + // Does this need to be before calling compiler? + optionsManager.makeTargetDir() + + // Output Annotations + val outputAnnos = firrtlConfig.getEmitterAnnos(optionsManager) + + val finalState = firrtlConfig.compiler.compile( + CircuitState(parsedInput, ChirrtlForm, Some(AnnotationMap(firrtlConfig.annotations ++ outputAnnos))), firrtlConfig.customTransforms ) - val outputFileName = firrtlConfig.getOutputFileName(optionsManager) - val outputFile = new java.io.PrintWriter(outputFileName) - val outputString = outputBuffer.toString - outputFile.write(outputString) - outputFile.close() + // Do emission + // Note: Single emission target assumption is baked in here + // Note: FirrtlExecutionSuccess emitted is only used if we're emitting the whole Circuit + val emittedRes = firrtlConfig.getOutputConfig(optionsManager) match { + case SingleFile(filename) => + finalState.emittedCircuitOption match { + case Some(emitted: EmittedCircuit) => + val outputFile = new java.io.PrintWriter(filename) + outputFile.write(emitted.value) + outputFile.close() + emitted.value + case _ => throwInternalError + } + case OneFilePerModule(dirName) => + val emittedModules = finalState.emittedComponents collect { case x: EmittedModule => x } + if (emittedModules.isEmpty) throwInternalError // There should be something + emittedModules.foreach { case module => + val filename = optionsManager.getBuildFileName(firrtlConfig.outputSuffix, s"$dirName/${module.name}") + val outputFile = new java.io.PrintWriter(filename) + outputFile.write(module.value) + outputFile.close() + } + "" // Should we return something different here? + } - FirrtlExecutionSuccess(firrtlConfig.compilerName, outputBuffer.toString) + FirrtlExecutionSuccess(firrtlConfig.compilerName, emittedRes) } /** diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 9ad97859..10d3ae85 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -12,6 +12,7 @@ import scala.io.Source import firrtl.ir._ import firrtl.passes._ +import firrtl.annotations._ import firrtl.Mappers._ import firrtl.PrimOps._ import firrtl.WrappedExpression._ @@ -22,10 +23,143 @@ import scala.collection.mutable.{ArrayBuffer, LinkedHashMap, HashSet} case class EmitterException(message: String) extends PassException(message) -class FirrtlEmitter extends Emitter { +// ***** Annotations for telling the Emitters what to emit ***** +sealed abstract class EmitAnnotation(marker: String) { + // TODO Is there a better way to do Name to indicate don't care? + def apply(transform: Class[_ <: Transform]): Annotation = + Annotation(CircuitTopName, transform, marker) + def unapply(a: Annotation): Boolean = a match { + // Assumes transform is already filtered appropriately + case Annotation(CircuitTopName, _, str) if str == marker => true + case _ => false + } +} +object EmitCircuitAnnotation extends EmitAnnotation("emitCircuit") +object EmitAllModulesAnnotation extends EmitAnnotation("emitAllModules") + +// ***** Annotations for results of emission ***** +sealed abstract class EmittedComponent { + def name: String + def value: String +} +sealed abstract class EmittedCircuit extends EmittedComponent +final case class EmittedFirrtlCircuit(name: String, value: String) extends EmittedCircuit +final case class EmittedVerilogCircuit(name: String, value: String) extends EmittedCircuit +sealed abstract class EmittedModule extends EmittedComponent +final case class EmittedFirrtlModule(name: String, value: String) extends EmittedModule +final case class EmittedVerilogModule(name: String, value: String) extends EmittedModule + +/** Super class for Annotations containing emitted components + * + * @note These annotations cannot be serialized and deserialized to/from an annotation file + */ +sealed abstract class EmittedAnnotation[T <: EmittedComponent](marker: String) { + // Private datastructure to hold the actual emitted objects + // TODO Once annotations can contain arbitrary datastructures, get rid of this + private val emittedBuffer = mutable.ArrayBuffer.empty[T] + + def apply(value: T): Annotation = { + // Synchronize because of multithreading + // This doesn't happen often, shouldn't be a big deal for performance + val idx = emittedBuffer.synchronized { + emittedBuffer += value + emittedBuffer.size - 1 + } + Annotation(CircuitTopName, classOf[Transform], s"$marker:$idx") + } + def unapply(a: Annotation): Option[T] = a match { + // assume transform has been filtered + case Annotation(CircuitTopName, _, str) if str.startsWith(marker) => + val idx = str.stripPrefix(s"$marker:").toInt + Some(emittedBuffer(idx)) + case _ => None + } +} + +object EmittedFirrtlCircuitAnnotation extends EmittedAnnotation[EmittedFirrtlCircuit]("emittedFirrtlCircuit") +object EmittedVerilogCircuitAnnotation extends EmittedAnnotation[EmittedVerilogCircuit]("emittedVerilogCircuit") +object EmittedCircuitAnnotation { + def apply(value: EmittedCircuit): Annotation = value match { + case firrtl: EmittedFirrtlCircuit => EmittedFirrtlCircuitAnnotation(firrtl) + case verilog: EmittedVerilogCircuit => EmittedVerilogCircuitAnnotation(verilog) + } + def unapply(a: Annotation): Option[EmittedCircuit] = a match { + case EmittedFirrtlCircuitAnnotation(x) => Some(x) + case EmittedVerilogCircuitAnnotation(x) => Some(x) + case _ => None + } +} +object EmittedFirrtlModuleAnnotation extends EmittedAnnotation[EmittedFirrtlModule]("emittedFirrtlModule") +object EmittedVerilogModuleAnnotation extends EmittedAnnotation[EmittedVerilogModule]("emittedVerilogModule") +object EmittedModuleAnnotation { + def apply(value: EmittedModule): Annotation = value match { + case firrtl: EmittedFirrtlModule => EmittedFirrtlModuleAnnotation(firrtl) + case verilog: EmittedVerilogModule => EmittedVerilogModuleAnnotation(verilog) + } + def unapply(a: Annotation): Option[EmittedModule] = a match { + case EmittedFirrtlModuleAnnotation(x) => Some(x) + case EmittedVerilogModuleAnnotation(x) => Some(x) + case _ => None + } +} + + +sealed abstract class FirrtlEmitter(form: CircuitForm) extends Transform with Emitter { + def inputForm = form + def outputForm = form + + private def emitAllModules(circuit: Circuit): Seq[EmittedFirrtlModule] = { + // For a given module, returns a Seq of all modules instantited inside of it + def collectInstantiatedModules(mod: Module, map: Map[String, DefModule]): Seq[DefModule] = { + // Use list instead of set to maintain order + val modules = mutable.ArrayBuffer.empty[DefModule] + def onStmt(stmt: Statement): Statement = stmt match { + case DefInstance(_, _, name) => + modules += map(name) + stmt + case WDefInstance(_, _, name, _) => + modules += map(name) + stmt + case _: WDefInstanceConnector => throwInternalError + case other => other map onStmt + } + onStmt(mod.body) + modules.distinct + } + val modMap = circuit.modules.map(m => m.name -> m).toMap + // Turn each module into it's own circuit with it as the top and all instantied modules as ExtModules + circuit.modules collect { case m: Module => + val instModules = collectInstantiatedModules(m, modMap) + val extModules = instModules map { + case Module(info, name, ports, _) => ExtModule(info, name, ports, name, Seq.empty) + case ext: ExtModule => ext + } + val newCircuit = Circuit(m.info, extModules :+ m, m.name) + EmittedFirrtlModule(m.name, newCircuit.serialize) + } + } + + def execute(state: CircuitState): CircuitState = { + val newAnnos = getMyAnnotations(state).flatMap { + case EmitCircuitAnnotation() => + Seq(EmittedFirrtlCircuitAnnotation.apply( + EmittedFirrtlCircuit(state.circuit.main, state.circuit.serialize))) + case EmitAllModulesAnnotation() => + emitAllModules(state.circuit) map (EmittedFirrtlModuleAnnotation(_)) + case _ => Seq() + } + state.copy(annotations = Some(AnnotationMap(newAnnos))) + } + + // Old style, deprecated def emit(state: CircuitState, writer: Writer): Unit = writer.write(state.circuit.serialize) } +// ***** Start actual Emitters ***** +class HighFirrtlEmitter extends FirrtlEmitter(HighForm) +class MiddleFirrtlEmitter extends FirrtlEmitter(HighForm) +class LowFirrtlEmitter extends FirrtlEmitter(HighForm) + case class VRandom(width: BigInt) extends Expression { def tpe = UIntType(IntWidth(width)) def nWords = (width + 31) / 32 @@ -36,7 +170,10 @@ case class VRandom(width: BigInt) extends Expression { def mapWidth(f: Width => Width): Expression = this } -class VerilogEmitter extends Emitter with PassBased { +class VerilogEmitter extends Transform with PassBased with Emitter { + def inputForm = LowForm + def outputForm = LowForm + val tab = " " def AND(e1: WrappedExpression, e2: WrappedExpression): Expression = { if (e1 == e2) e1.e1 @@ -583,21 +720,22 @@ class VerilogEmitter extends Emitter with PassBased { m } - def emit_preamble(implicit w: Writer) { - emit(Seq( - "`ifdef RANDOMIZE_GARBAGE_ASSIGN\n", - "`define RANDOMIZE\n", - "`endif\n", - "`ifdef RANDOMIZE_INVALID_ASSIGN\n", - "`define RANDOMIZE\n", - "`endif\n", - "`ifdef RANDOMIZE_REG_INIT\n", - "`define RANDOMIZE\n", - "`endif\n", - "`ifdef RANDOMIZE_MEM_INIT\n", - "`define RANDOMIZE\n", - "`endif\n")) - } + /** Preamble for every emitted Verilog file */ + def preamble: String = + """|`ifdef RANDOMIZE_GARBAGE_ASSIGN + |`define RANDOMIZE + |`endif + |`ifdef RANDOMIZE_INVALID_ASSIGN + |`define RANDOMIZE + |`endif + |`ifdef RANDOMIZE_REG_INIT + |`define RANDOMIZE + |`endif + |`ifdef RANDOMIZE_MEM_INIT + |`define RANDOMIZE + |`endif + | + |""".stripMargin def passSeq = Seq( passes.VerilogModulusCleanup, @@ -606,12 +744,37 @@ class VerilogEmitter extends Emitter with PassBased { passes.VerilogPrep) def emit(state: CircuitState, writer: Writer): Unit = { + writer.write(preamble) + val circuit = runPasses(state.circuit) - emit_preamble(writer) - val moduleMap = (circuit.modules map (m => m.name -> m)).toMap - circuit.modules foreach { - case (m: Module) => emit_verilog(m, moduleMap)(writer) - case (m: ExtModule) => + val moduleMap = circuit.modules.map(m => m.name -> m).toMap + circuit.modules.foreach { + case m: Module => emit_verilog(m, moduleMap)(writer) + case _: ExtModule => // do nothing + } + } + + def execute(state: CircuitState): CircuitState = { + val newAnnos = getMyAnnotations(state).flatMap { + case EmitCircuitAnnotation() => + val writer = new java.io.StringWriter + emit(state, writer) + Seq(EmittedVerilogCircuitAnnotation(EmittedVerilogCircuit(state.circuit.main, writer.toString))) + + case EmitAllModulesAnnotation() => + val circuit = runPasses(state.circuit) + val moduleMap = circuit.modules.map(m => m.name -> m).toMap + + circuit.modules flatMap { + case module: Module => + val writer = new java.io.StringWriter + writer.write(preamble) + emit_verilog(module, moduleMap)(writer) + Some(EmittedVerilogModuleAnnotation(EmittedVerilogModule(module.name, writer.toString))) + case _: ExtModule => None + } + case _ => Seq() } + state.copy(annotations = Some(AnnotationMap(newAnnos))) } } diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala index 5615da99..2d221e6b 100644 --- a/src/main/scala/firrtl/ExecutionOptionsManager.scala +++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala @@ -125,6 +125,15 @@ trait HasCommonOptions { parser.help("help").text("prints this usage text") } +/** 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 * @@ -133,7 +142,6 @@ trait HasCommonOptions { * @param compilerName which compiler to use * @param annotations annotations to pass to compiler */ - case class FirrtlExecutionOptions( inputFileNameOverride: String = "", outputFileNameOverride: String = "", @@ -144,9 +152,13 @@ case class FirrtlExecutionOptions( customTransforms: Seq[Transform] = List.empty, annotations: List[Annotation] = List.empty, annotationFileNameOverride: String = "", - forceAppendAnnoFile: Boolean = false) + forceAppendAnnoFile: Boolean = false, + emitOneFilePerModule: Boolean = false) 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 @@ -186,14 +198,43 @@ case class FirrtlExecutionOptions( def getInputFileName(optionsManager: ExecutionOptionsManager): String = { optionsManager.getBuildFileName("fir", inputFileNameOverride) } - /** - * build the output file name, taking overriding parameters + /** Get the user-specified [[OutputConfig]] * * @param optionsManager this is needed to access build function and its common options - * @return + * @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 getOutputFileName(optionsManager: ExecutionOptionsManager): String = { - optionsManager.getBuildFileName(outputSuffix, outputFileNameOverride) + 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 "high" => classOf[HighFirrtlEmitter] + case "middle" => classOf[MiddleFirrtlEmitter] + case "low" => classOf[LowFirrtlEmitter] + case "verilog" => classOf[VerilogEmitter] + } + getOutputConfig(optionsManager) match { + case SingleFile(_) => Seq(EmitCircuitAnnotation(emitter)) + case OneFilePerModule(_) => Seq(EmitAllModulesAnnotation(emitter)) + } } /** * build the annotation file name, taking overriding parameters @@ -223,8 +264,13 @@ trait HasFirrtlOptions { parser.opt[String]("output-file") .abbr("o") - .valueName ("<output>"). - foreach { x => + .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" @@ -234,7 +280,7 @@ trait HasFirrtlOptions { .abbr("faf") .valueName ("<output>"). foreach { x => - firrtlOptions = firrtlOptions.copy(outputFileNameOverride = x) + firrtlOptions = firrtlOptions.copy(annotationFileNameOverride = x) }.text { "use this to override the default annotation file name, default is empty" } @@ -334,8 +380,20 @@ trait HasFirrtlOptions { "List which signal drives each clock of every descendent of specified module" } - parser.note("") + 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.note("") } sealed trait FirrtlExecutionResult @@ -345,7 +403,7 @@ sealed trait FirrtlExecutionResult * the type of compile * * @param emitType The name of the compiler used, currently "high", "middle", "low", or "verilog" - * @param emitted The text result of the compilation, could be verilog or firrtl text. + * @param emitted The emitted result of compilation */ case class FirrtlExecutionSuccess(emitType: String, emitted: String) extends FirrtlExecutionResult diff --git a/src/main/scala/firrtl/LoweringCompilers.scala b/src/main/scala/firrtl/LoweringCompilers.scala index 1a4b24cd..ab9f6ea4 100644 --- a/src/main/scala/firrtl/LoweringCompilers.scala +++ b/src/main/scala/firrtl/LoweringCompilers.scala @@ -116,25 +116,25 @@ import firrtl.transforms.BlackBoxSourceHelper * Will replace Chirrtl constructs with Firrtl */ class HighFirrtlCompiler extends Compiler { - def emitter = new FirrtlEmitter + def emitter = new HighFirrtlEmitter def transforms: Seq[Transform] = getLoweringTransforms(ChirrtlForm, HighForm) } /** Emits middle Firrtl input circuit */ class MiddleFirrtlCompiler extends Compiler { - def emitter = new FirrtlEmitter + def emitter = new MiddleFirrtlEmitter def transforms: Seq[Transform] = getLoweringTransforms(ChirrtlForm, MidForm) } /** Emits lowered input circuit */ class LowFirrtlCompiler extends Compiler { - def emitter = new FirrtlEmitter + def emitter = new LowFirrtlEmitter def transforms: Seq[Transform] = getLoweringTransforms(ChirrtlForm, LowForm) } /** Emits Verilog */ class VerilogCompiler extends Compiler { def emitter = new VerilogEmitter - def transforms: Seq[Transform] = - getLoweringTransforms(ChirrtlForm, LowForm) ++ Seq(new LowFirrtlOptimization, new BlackBoxSourceHelper) + def transforms: Seq[Transform] = getLoweringTransforms(ChirrtlForm, LowForm) ++ + Seq(new LowFirrtlOptimization, new BlackBoxSourceHelper) } diff --git a/src/main/scala/firrtl/annotations/Named.scala b/src/main/scala/firrtl/annotations/Named.scala index 4b39c977..0e365249 100644 --- a/src/main/scala/firrtl/annotations/Named.scala +++ b/src/main/scala/firrtl/annotations/Named.scala @@ -14,6 +14,12 @@ sealed trait Named { def serialize: String } +/** Name referring to the top of the circuit */ +final case object CircuitTopName extends Named { + def name: String = "CircuitTop" + def serialize: String = name +} + final case class CircuitName(name: String) extends Named { if(!validModuleName(name)) throw AnnotationException(s"Illegal circuit name: $name") def serialize: String = name |
