aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/Emitter.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/firrtl/Emitter.scala')
-rw-r--r--src/main/scala/firrtl/Emitter.scala117
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"
+}