diff options
Diffstat (limited to 'src/main/scala/firrtl/Emitter.scala')
| -rw-r--r-- | src/main/scala/firrtl/Emitter.scala | 117 |
1 files changed, 91 insertions, 26 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 7204eea6..44190b39 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -19,6 +19,9 @@ import firrtl.PrimOps._ import firrtl.WrappedExpression._ import Utils._ import MemPortUtils.{memPortField, memType} +import firrtl.options.{HasScoptOptions, StageUtils, PhaseException} +import firrtl.stage.RunFirrtlTransformAnnotation +import scopt.OptionParser // Datastructures import scala.collection.mutable.{ArrayBuffer, LinkedHashMap, HashSet} @@ -31,17 +34,70 @@ 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 { + case "chirrtl" => Seq(RunFirrtlTransformAnnotation(new ChirrtlEmitter), + EmitCircuitAnnotation(classOf[ChirrtlEmitter])) + case "high" => Seq(RunFirrtlTransformAnnotation(new HighFirrtlEmitter), + EmitCircuitAnnotation(classOf[HighFirrtlEmitter])) + case "middle" => Seq(RunFirrtlTransformAnnotation(new MiddleFirrtlEmitter), + EmitCircuitAnnotation(classOf[MiddleFirrtlEmitter])) + case "low" => Seq(RunFirrtlTransformAnnotation(new LowFirrtlEmitter), + EmitCircuitAnnotation(classOf[LowFirrtlEmitter])) + case "verilog" | "mverilog" => Seq(RunFirrtlTransformAnnotation(new VerilogEmitter), + 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)") +} + +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 { + case "chirrtl" => Seq(RunFirrtlTransformAnnotation(new ChirrtlEmitter), + EmitAllModulesAnnotation(classOf[ChirrtlEmitter])) + case "high" => Seq(RunFirrtlTransformAnnotation(new HighFirrtlEmitter), + EmitAllModulesAnnotation(classOf[HighFirrtlEmitter])) + case "middle" => Seq(RunFirrtlTransformAnnotation(new MiddleFirrtlEmitter), + EmitAllModulesAnnotation(classOf[MiddleFirrtlEmitter])) + case "low" => Seq(RunFirrtlTransformAnnotation(new LowFirrtlEmitter), + EmitAllModulesAnnotation(classOf[LowFirrtlEmitter])) + case "verilog" | "mverilog" => Seq(RunFirrtlTransformAnnotation(new VerilogEmitter), + 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)") +} + // ***** Annotations for results of emission ***** sealed abstract class EmittedComponent { def name: String def value: String + def outputSuffix: 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 +final case class EmittedFirrtlCircuit(name: String, value: String, outputSuffix: String) extends EmittedCircuit +final case class EmittedVerilogCircuit(name: String, value: String, outputSuffix: 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 +final case class EmittedFirrtlModule(name: String, value: String, outputSuffix: String) extends EmittedModule +final case class EmittedVerilogModule(name: String, value: String, outputSuffix: String) extends EmittedModule /** Traits for Annotations containing emitted components */ sealed trait EmittedAnnotation[T <: EmittedComponent] extends NoTargetAnnotation { @@ -51,19 +107,21 @@ sealed trait EmittedCircuitAnnotation[T <: EmittedCircuit] extends EmittedAnnota sealed trait EmittedModuleAnnotation[T <: EmittedModule] extends EmittedAnnotation[T] case class EmittedFirrtlCircuitAnnotation(value: EmittedFirrtlCircuit) - extends EmittedCircuitAnnotation[EmittedFirrtlCircuit] + extends EmittedCircuitAnnotation[EmittedFirrtlCircuit] case class EmittedVerilogCircuitAnnotation(value: EmittedVerilogCircuit) - extends EmittedCircuitAnnotation[EmittedVerilogCircuit] + extends EmittedCircuitAnnotation[EmittedVerilogCircuit] case class EmittedFirrtlModuleAnnotation(value: EmittedFirrtlModule) - extends EmittedModuleAnnotation[EmittedFirrtlModule] + extends EmittedModuleAnnotation[EmittedFirrtlModule] case class EmittedVerilogModuleAnnotation(value: EmittedVerilogModule) - extends EmittedModuleAnnotation[EmittedVerilogModule] + extends EmittedModuleAnnotation[EmittedVerilogModule] sealed abstract class FirrtlEmitter(form: CircuitForm) extends Transform with Emitter { def inputForm = form def outputForm = form + val outputSuffix: String = form.outputSuffix + 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] = { @@ -87,15 +145,15 @@ sealed abstract class FirrtlEmitter(form: CircuitForm) extends Transform with Em case ext: ExtModule => ext } val newCircuit = Circuit(m.info, extModules :+ m, m.name) - EmittedFirrtlModule(m.name, newCircuit.serialize) + EmittedFirrtlModule(m.name, newCircuit.serialize, outputSuffix) } } override def execute(state: CircuitState): CircuitState = { val newAnnos = state.annotations.flatMap { case EmitCircuitAnnotation(_) => - Seq(EmittedFirrtlCircuitAnnotation.apply( - EmittedFirrtlCircuit(state.circuit.main, state.circuit.serialize))) + Seq(EmittedFirrtlCircuitAnnotation( + EmittedFirrtlCircuit(state.circuit.main, state.circuit.serialize, outputSuffix))) case EmitAllModulesAnnotation(_) => emitAllModules(state.circuit) map (EmittedFirrtlModuleAnnotation(_)) case _ => Seq() @@ -129,6 +187,7 @@ case class VRandom(width: BigInt) extends Expression { class VerilogEmitter extends SeqTransform with Emitter { def inputForm = LowForm def outputForm = LowForm + val outputSuffix = ".v" val tab = " " def AND(e1: WrappedExpression, e2: WrappedExpression): Expression = { if (e1 == e2) e1.e1 @@ -363,8 +422,8 @@ class VerilogEmitter extends SeqTransform with Emitter { * @return the render reference */ def getRenderer(descriptions: Seq[DescriptionAnnotation], - m: Module, - moduleMap: Map[String, DefModule])(implicit writer: Writer): VerilogRender = { + m: Module, + moduleMap: Map[String, DefModule])(implicit writer: Writer): VerilogRender = { val newMod = new AddDescriptionNodes().executeModule(m, descriptions) newMod match { @@ -384,9 +443,9 @@ class VerilogEmitter extends SeqTransform with Emitter { * @param writer where rendered information is placed. */ class VerilogRender(description: Description, - portDescriptions: Map[String, Description], - m: Module, - moduleMap: Map[String, DefModule])(implicit writer: Writer) { + portDescriptions: Map[String, Description], + m: Module, + moduleMap: Map[String, DefModule])(implicit writer: Writer) { def this(m: Module, moduleMap: Map[String, DefModule])(implicit writer: Writer) { this(EmptyDescription, Map.empty, m, moduleMap)(writer) @@ -458,7 +517,7 @@ class VerilogEmitter extends SeqTransform with Emitter { assigns += Seq("assign ", e, " = ", syn, ";", info) assigns += Seq("`else") assigns += Seq("assign ", e, " = ", garbageCond, " ? ", rand_string(syn.tpe), " : ", syn, - ";", info) + ";", info) assigns += Seq("`endif // RANDOMIZE_GARBAGE_ASSIGN") } @@ -550,7 +609,7 @@ class VerilogEmitter extends SeqTransform with Emitter { initials += Seq("`ifdef RANDOMIZE_MEM_INIT") initials += Seq("for (initvar = 0; initvar < ", bigIntToVLit(s.depth), "; initvar = initvar+1)") initials += Seq(tab, WSubAccess(wref(s.name, s.dataType), index, s.dataType, FEMALE), - " = ", rstring, ";") + " = ", rstring, ";") initials += Seq("`endif // RANDOMIZE_MEM_INIT") } @@ -696,14 +755,14 @@ class VerilogEmitter extends SeqTransform with Emitter { instdeclares += Seq(");") case sx: DefMemory => val fullSize = sx.depth * (sx.dataType match { - case GroundType(IntWidth(width)) => width - }) + case GroundType(IntWidth(width)) => width + }) val decl = if (fullSize > (1 << 29)) "reg /* sparse */" else "reg" declareVectorType(decl, sx.name, sx.dataType, sx.depth, sx.info) initialize_mem(sx) if (sx.readLatency != 0 || sx.writeLatency != 1) throw EmitterException("All memories should be transformed into " + - "blackboxes or combinational by previous passses") + "blackboxes or combinational by previous passses") for (r <- sx.readers) { val data = memPortField(sx, r, "data") val addr = memPortField(sx, r, "addr") @@ -717,7 +776,7 @@ class VerilogEmitter extends SeqTransform with Emitter { //; Read port assign(addr, netlist(addr), NoInfo) // Info should come from addr connection - // assign(en, netlist(en)) //;Connects value to m.r.en + // assign(en, netlist(en)) //;Connects value to m.r.en val mem = WRef(sx.name, memType(sx), MemKind, UNKNOWNGENDER) val memPort = WSubAccess(mem, addr, sx.dataType, UNKNOWNGENDER) val depthValue = UIntLiteral(sx.depth, IntWidth(sx.depth.bitLength)) @@ -756,7 +815,7 @@ class VerilogEmitter extends SeqTransform with Emitter { if (sx.readwriters.nonEmpty) throw EmitterException("All readwrite ports should be transformed into " + - "read & write ports by previous passes") + "read & write ports by previous passes") case _ => } } @@ -918,7 +977,7 @@ class VerilogEmitter extends SeqTransform with Emitter { case EmitCircuitAnnotation(_) => val writer = new java.io.StringWriter emit(state, writer) - Seq(EmittedVerilogCircuitAnnotation(EmittedVerilogCircuit(state.circuit.main, writer.toString))) + Seq(EmittedVerilogCircuitAnnotation(EmittedVerilogCircuit(state.circuit.main, writer.toString, outputSuffix))) case EmitAllModulesAnnotation(_) => val circuit = runTransforms(state).circuit @@ -929,12 +988,12 @@ class VerilogEmitter extends SeqTransform with Emitter { val writer = new java.io.StringWriter val renderer = new VerilogRender(d, pds, module, moduleMap)(writer) renderer.emit_verilog() - Some(EmittedVerilogModuleAnnotation(EmittedVerilogModule(module.name, writer.toString))) + Some(EmittedVerilogModuleAnnotation(EmittedVerilogModule(module.name, writer.toString, outputSuffix))) case module: Module => val writer = new java.io.StringWriter val renderer = new VerilogRender(module, moduleMap)(writer) renderer.emit_verilog() - Some(EmittedVerilogModuleAnnotation(EmittedVerilogModule(module.name, writer.toString))) + Some(EmittedVerilogModuleAnnotation(EmittedVerilogModule(module.name, writer.toString, outputSuffix))) case _ => None } case _ => Seq() @@ -952,3 +1011,9 @@ class MinimumVerilogEmitter extends VerilogEmitter with Emitter { } } + +class SystemVerilogEmitter extends VerilogEmitter { + StageUtils.dramaticWarning("SystemVerilog Emitter is the same as the Verilog Emitter!") + + override val outputSuffix: String = ".sv" +} |
