aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/Emitter.scala
diff options
context:
space:
mode:
authorchick2020-08-14 19:47:53 -0700
committerJack Koenig2020-08-14 19:47:53 -0700
commit6fc742bfaf5ee508a34189400a1a7dbffe3f1cac (patch)
tree2ed103ee80b0fba613c88a66af854ae9952610ce /src/main/scala/firrtl/Emitter.scala
parentb516293f703c4de86397862fee1897aded2ae140 (diff)
All of src/ formatted with scalafmt
Diffstat (limited to 'src/main/scala/firrtl/Emitter.scala')
-rw-r--r--src/main/scala/firrtl/Emitter.scala807
1 files changed, 466 insertions, 341 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala
index ae9a7dad..843c76a4 100644
--- a/src/main/scala/firrtl/Emitter.scala
+++ b/src/main/scala/firrtl/Emitter.scala
@@ -37,28 +37,38 @@ object EmitCircuitAnnotation extends HasShellOptions {
val options = Seq(
new ShellOption[String](
longOption = "emit-circuit",
- toAnnotationSeq = (a: String) => a 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 "experimental-btor2" => Seq(RunFirrtlTransformAnnotation(new Btor2Emitter),
- EmitCircuitAnnotation(classOf[Btor2Emitter]))
- case "experimental-smt2" => Seq(RunFirrtlTransformAnnotation(new SMTLibEmitter),
- EmitCircuitAnnotation(classOf[SMTLibEmitter]))
- case _ => throw new PhaseException(s"Unknown emitter '$a'! (Did you misspell it?)") },
+ toAnnotationSeq = (a: String) =>
+ a 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 "experimental-btor2" =>
+ Seq(RunFirrtlTransformAnnotation(new Btor2Emitter), EmitCircuitAnnotation(classOf[Btor2Emitter]))
+ case "experimental-smt2" =>
+ Seq(RunFirrtlTransformAnnotation(new SMTLibEmitter), EmitCircuitAnnotation(classOf[SMTLibEmitter]))
+ case _ => throw new PhaseException(s"Unknown emitter '$a'! (Did you misspell it?)")
+ },
helpText = "Run the specified circuit emitter (all modules in one file)",
shortOption = Some("E"),
// the experimental options are intentionally excluded from the help message
- helpValueName = Some("<chirrtl|high|middle|low|verilog|mverilog|sverilog>") ) )
+ helpValueName = Some("<chirrtl|high|middle|low|verilog|mverilog|sverilog>")
+ )
+ )
}
@@ -67,30 +77,43 @@ object EmitAllModulesAnnotation extends HasShellOptions {
val options = Seq(
new ShellOption[String](
longOption = "emit-modules",
- toAnnotationSeq = (a: String) => a 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 '$a'! (Did you misspell it?)") },
+ toAnnotationSeq = (a: String) =>
+ a 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 '$a'! (Did you misspell it?)")
+ },
helpText = "Run the specified module emitter (one file per module)",
shortOption = Some("e"),
- helpValueName = Some("<chirrtl|high|middle|low|verilog|mverilog|sverilog>") ) )
+ helpValueName = Some("<chirrtl|high|middle|low|verilog|mverilog|sverilog>")
+ )
+ )
}
// ***** Annotations for results of emission *****
sealed abstract class EmittedComponent {
- def name: String
- def value: String
+ def name: String
+ def value: String
def outputSuffix: String
}
sealed abstract class EmittedCircuit extends EmittedComponent
@@ -147,7 +170,7 @@ sealed abstract class FirrtlEmitter(form: CircuitForm) extends Transform with Em
// Use list instead of set to maintain order
val modules = mutable.ArrayBuffer.empty[DefModule]
def onStmt(stmt: Statement): Unit = stmt match {
- case DefInstance(_, _, name, _) => modules += map(name)
+ case DefInstance(_, _, name, _) => modules += map(name)
case WDefInstance(_, _, name, _) => modules += map(name)
case _: WDefInstanceConnector => throwInternalError(s"unrecognized statement: $stmt")
case other => other.foreach(onStmt)
@@ -157,24 +180,28 @@ sealed abstract class FirrtlEmitter(form: CircuitForm) extends Transform with Em
}
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, outputSuffix)
+ 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, outputSuffix)
}
}
override def execute(state: CircuitState): CircuitState = {
val newAnnos = state.annotations.flatMap {
case EmitCircuitAnnotation(a) if this.getClass == a =>
- Seq(EmittedFirrtlCircuitAnnotation(
- EmittedFirrtlCircuit(state.circuit.main, state.circuit.serialize, outputSuffix)))
+ Seq(
+ EmittedFirrtlCircuitAnnotation(
+ EmittedFirrtlCircuit(state.circuit.main, state.circuit.serialize, outputSuffix)
+ )
+ )
case EmitAllModulesAnnotation(a) if this.getClass == a =>
- emitAllModules(state.circuit) map (EmittedFirrtlModuleAnnotation(_))
+ emitAllModules(state.circuit).map(EmittedFirrtlModuleAnnotation(_))
case _ => Seq()
}
state.copy(annotations = newAnnos ++ state.annotations)
@@ -195,12 +222,12 @@ case class VRandom(width: BigInt) extends Expression {
def nWords = (width + 31) / 32
def realWidth = nWords * 32
override def serialize: String = "RANDOM"
- def mapExpr(f: Expression => Expression): Expression = this
- def mapType(f: Type => Type): Expression = this
- def mapWidth(f: Width => Width): Expression = this
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = ()
- def foreachWidth(f: Width => Unit): Unit = ()
+ def mapExpr(f: Expression => Expression): Expression = this
+ def mapType(f: Type => Type): Expression = this
+ def mapWidth(f: Width => Width): Expression = this
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachWidth(f: Width => Unit): Unit = ()
}
class VerilogEmitter extends SeqTransform with Emitter {
@@ -221,14 +248,16 @@ class VerilogEmitter extends SeqTransform with Emitter {
else if (e2 == we(one)) e1.e1
else DoPrim(And, Seq(e1.e1, e2.e1), Nil, UIntType(IntWidth(1)))
}
- def wref(n: String, t: Type) = WRef(n, t, ExpKind, UnknownFlow)
+ def wref(n: String, t: Type) = WRef(n, t, ExpKind, UnknownFlow)
def remove_root(ex: Expression): Expression = ex match {
- case ex: WSubField => ex.expr match {
- case (e: WSubField) => remove_root(e)
- case (_: WRef) => WRef(ex.name, ex.tpe, InstanceKind, UnknownFlow)
- }
+ case ex: WSubField =>
+ ex.expr match {
+ case (e: WSubField) => remove_root(e)
+ case (_: WRef) => WRef(ex.name, ex.tpe, InstanceKind, UnknownFlow)
+ }
case _ => throwInternalError(s"shouldn't be here: remove_root($ex)")
}
+
/** Turn Params into Verilog Strings */
def stringify(param: Param): String = param match {
case IntParam(name, value) =>
@@ -237,11 +266,11 @@ class VerilogEmitter extends SeqTransform with Emitter {
s"$value"
} else {
val blen = value.bitLength
- if (value > 0) s"$blen'd$value" else s"-${blen+1}'sd${value.abs}"
+ if (value > 0) s"$blen'd$value" else s"-${blen + 1}'sd${value.abs}"
}
s".$name($lit)"
- case DoubleParam(name, value) => s".$name($value)"
- case StringParam(name, value) => s".${name}(${value.verilogEscape})"
+ case DoubleParam(name, value) => s".$name($value)"
+ case StringParam(name, value) => s".${name}(${value.verilogEscape})"
case RawStringParam(name, value) => s".$name($value)"
}
def stringify(tpe: GroundType): String = tpe match {
@@ -249,16 +278,16 @@ class VerilogEmitter extends SeqTransform with Emitter {
val wx = bitWidth(tpe) - 1
if (wx > 0) s"[$wx:0]" else ""
case ClockType | AsyncResetType => ""
- case _ => throwInternalError(s"trying to write unsupported type in the Verilog Emitter: $tpe")
+ case _ => throwInternalError(s"trying to write unsupported type in the Verilog Emitter: $tpe")
}
def emit(x: Any)(implicit w: Writer): Unit = { emit(x, 0) }
def emit(x: Any, top: Int)(implicit w: Writer): Unit = {
def cast(e: Expression): Any = e.tpe match {
case (t: UIntType) => e
- case (t: SIntType) => Seq("$signed(",e,")")
- case ClockType => e
+ case (t: SIntType) => Seq("$signed(", e, ")")
+ case ClockType => e
case AnalogType(_) => e
- case _ => throwInternalError(s"unrecognized cast: $e")
+ case _ => throwInternalError(s"unrecognized cast: $e")
}
x match {
case (e: DoPrim) => emit(op_stream(e), top + 1)
@@ -269,186 +298,190 @@ class VerilogEmitter extends SeqTransform with Emitter {
if (e.tpe == AsyncResetType) {
throw EmitterException("Cannot emit async reset muxes directly")
}
- emit(Seq(e.cond," ? ",cast(e.tval)," : ",cast(e.fval)),top + 1)
+ emit(Seq(e.cond, " ? ", cast(e.tval), " : ", cast(e.fval)), top + 1)
}
- case (e: ValidIf) => emit(Seq(cast(e.value)),top + 1)
- case (e: WRef) => w write e.serialize
- case (e: WSubField) => w write LowerTypes.loweredName(e)
- case (e: WSubAccess) => w write s"${LowerTypes.loweredName(e.expr)}[${LowerTypes.loweredName(e.index)}]"
- case (e: WSubIndex) => w write e.serialize
- case (e: Literal) => v_print(e)
- case (e: VRandom) => w write s"{${e.nWords}{`RANDOM}}"
- case (t: GroundType) => w write stringify(t)
+ case (e: ValidIf) => emit(Seq(cast(e.value)), top + 1)
+ case (e: WRef) => w.write(e.serialize)
+ case (e: WSubField) => w.write(LowerTypes.loweredName(e))
+ case (e: WSubAccess) => w.write(s"${LowerTypes.loweredName(e.expr)}[${LowerTypes.loweredName(e.index)}]")
+ case (e: WSubIndex) => w.write(e.serialize)
+ case (e: Literal) => v_print(e)
+ case (e: VRandom) => w.write(s"{${e.nWords}{`RANDOM}}")
+ case (t: GroundType) => w.write(stringify(t))
case (t: VectorType) =>
emit(t.tpe, top + 1)
- w write s"[${t.size - 1}:0]"
- case (s: String) => w write s
- case (i: Int) => w write i.toString
- case (i: Long) => w write i.toString
- case (i: BigInt) => w write i.toString
- case (i: Info) => i match {
- case NoInfo => // Do nothing
- case f: FileInfo =>
- val escaped = FileInfo.escapedToVerilog(f.escaped)
- w.write(s" // @[$escaped]")
- case m: MultiInfo =>
- val escaped = FileInfo.escapedToVerilog(m.flatten.map(_.escaped).mkString(" "))
- w.write(s" // @[$escaped]")
- }
+ w.write(s"[${t.size - 1}:0]")
+ case (s: String) => w.write(s)
+ case (i: Int) => w.write(i.toString)
+ case (i: Long) => w.write(i.toString)
+ case (i: BigInt) => w.write(i.toString)
+ case (i: Info) =>
+ i match {
+ case NoInfo => // Do nothing
+ case f: FileInfo =>
+ val escaped = FileInfo.escapedToVerilog(f.escaped)
+ w.write(s" // @[$escaped]")
+ case m: MultiInfo =>
+ val escaped = FileInfo.escapedToVerilog(m.flatten.map(_.escaped).mkString(" "))
+ w.write(s" // @[$escaped]")
+ }
case (s: Seq[Any]) =>
- s foreach (emit(_, top + 1))
- if (top == 0) w write "\n"
+ s.foreach(emit(_, top + 1))
+ if (top == 0) w.write("\n")
case x => throwInternalError(s"trying to emit unsupported operator: $x")
}
}
- //;------------- PASS -----------------
- def v_print(e: Expression)(implicit w: Writer) = e match {
- case UIntLiteral(value, IntWidth(width)) =>
- w write s"$width'h${value.toString(16)}"
- case SIntLiteral(value, IntWidth(width)) =>
- val stringLiteral = value.toString(16)
- w write (stringLiteral.head match {
- case '-' if value == FixAddingNegativeLiterals.minNegValue(width) => s"$width'sh${stringLiteral.tail}"
- case '-' => s"-$width'sh${stringLiteral.tail}"
- case _ => s"$width'sh${stringLiteral}"
- })
- case _ => throwInternalError(s"attempt to print unrecognized expression: $e")
- }
-
- // NOTE: We emit SInts as regular Verilog unsigned wires/regs so the real type of any SInt
- // reference is actually unsigned in the emitted Verilog. Thus we must cast refs as necessary
- // to ensure Verilog operations are signed.
- def op_stream(doprim: DoPrim): Seq[Any] = {
- // Cast to SInt, don't cast multiple times
- def doCast(e: Expression): Any = e match {
- case DoPrim(AsSInt, Seq(arg), _,_) => doCast(arg)
- case slit: SIntLiteral => slit
- case other => Seq("$signed(", other, ")")
- }
- def castIf(e: Expression): Any = {
- if (doprim.args.exists(_.tpe.isInstanceOf[SIntType])) {
- e.tpe match {
- case _: SIntType => doCast(e)
- case _ => throwInternalError(s"Unexpected non-SInt type for $e in $doprim")
- }
- } else {
- e
- }
- }
- def cast(e: Expression): Any = doprim.tpe match {
- case _: UIntType => e
- case _: SIntType => doCast(e)
- case _ => throwInternalError(s"Unexpected type for $e in $doprim")
- }
- def castAs(e: Expression): Any = e.tpe match {
- case _: UIntType => e
- case _: SIntType => doCast(e)
- case _ => throwInternalError(s"Unexpected type for $e in $doprim")
- }
- def a0: Expression = doprim.args.head
- def a1: Expression = doprim.args(1)
- def c0: Int = doprim.consts.head.toInt
- def c1: Int = doprim.consts(1).toInt
-
- def checkArgumentLegality(e: Expression): Unit = e match {
- case _: UIntLiteral | _: SIntLiteral | _: WRef | _: WSubField =>
- case DoPrim(Not, args, _,_) => args.foreach(checkArgumentLegality)
- case DoPrim(op, args, _,_) if isCast(op) => args.foreach(checkArgumentLegality)
- case DoPrim(op, args, _,_) if isBitExtract(op) => args.foreach(checkArgumentLegality)
- case _ => throw EmitterException(s"Can't emit ${e.getClass.getName} as PrimOp argument")
- }
-
- def checkCatArgumentLegality(e: Expression): Unit = e match {
- case DoPrim(Cat, args, _, _) => args foreach(checkCatArgumentLegality)
- case _ => checkArgumentLegality(e)
- }
-
- def castCatArgs(a0: Expression, a1: Expression): Seq[Any] = {
- val a0Seq = a0 match {
- case cat@DoPrim(PrimOps.Cat, args, _, _) => castCatArgs(args.head, args(1))
- case _ => Seq(cast(a0))
- }
- val a1Seq = a1 match {
- case cat@DoPrim(PrimOps.Cat, args, _, _) => castCatArgs(args.head, args(1))
- case _ => Seq(cast(a1))
- }
- a0Seq ++ Seq(",") ++ a1Seq
- }
-
- doprim.op match {
- case Cat => doprim.args foreach(checkCatArgumentLegality)
- case cast if isCast(cast) => // Casts are allowed to wrap any Expression
- case other => doprim.args foreach checkArgumentLegality
- }
- doprim.op match {
- case Add => Seq(castIf(a0), " + ", castIf(a1))
- case Addw => Seq(castIf(a0), " + ", castIf(a1))
- case Sub => Seq(castIf(a0), " - ", castIf(a1))
- case Subw => Seq(castIf(a0), " - ", castIf(a1))
- case Mul => Seq(castIf(a0), " * ", castIf(a1))
- case Div => Seq(castIf(a0), " / ", castIf(a1))
- case Rem => Seq(castIf(a0), " % ", castIf(a1))
- case Lt => Seq(castIf(a0), " < ", castIf(a1))
- case Leq => Seq(castIf(a0), " <= ", castIf(a1))
- case Gt => Seq(castIf(a0), " > ", castIf(a1))
- case Geq => Seq(castIf(a0), " >= ", castIf(a1))
- case Eq => Seq(castIf(a0), " == ", castIf(a1))
- case Neq => Seq(castIf(a0), " != ", castIf(a1))
- case Pad =>
- val w = bitWidth(a0.tpe)
- val diff = c0 - w
- if (w == BigInt(0) || diff <= 0) Seq(a0)
- else doprim.tpe match {
- // Either sign extend or zero extend.
- // If width == BigInt(1), don't extract bit
- case (_: SIntType) if w == BigInt(1) => Seq("{", c0, "{", a0, "}}")
- case (_: SIntType) => Seq("{{", diff, "{", a0, "[", w - 1, "]}},", a0, "}")
- case (_) => Seq("{{", diff, "'d0}, ", a0, "}")
- }
- // Because we don't support complex Expressions, all casts are ignored
- // This simplifies handling of assignment of a signed expression to an unsigned LHS value
- // which does not require a cast in Verilog
- case AsUInt | AsSInt | AsClock | AsAsyncReset => Seq(a0)
- case Dshlw => Seq(cast(a0), " << ", a1)
- case Dshl => Seq(cast(a0), " << ", a1)
- case Dshr => doprim.tpe match {
- case (_: SIntType) => Seq(cast(a0)," >>> ", a1)
- case (_) => Seq(cast(a0), " >> ", a1)
- }
- case Shl => if (c0 > 0) Seq("{", cast(a0), s", $c0'h0}") else Seq(cast(a0))
- case Shr if c0 >= bitWidth(a0.tpe) =>
- error("Verilog emitter does not support SHIFT_RIGHT >= arg width")
- case Shr if c0 == (bitWidth(a0.tpe)-1) => Seq(a0,"[", bitWidth(a0.tpe) - 1, "]")
- case Shr => Seq(a0,"[", bitWidth(a0.tpe) - 1, ":", c0, "]")
- case Neg => Seq("-", cast(a0))
- case Cvt => a0.tpe match {
- case (_: UIntType) => Seq("{1'b0,", cast(a0), "}")
- case (_: SIntType) => Seq(cast(a0))
- }
- case Not => Seq("~", a0)
- case And => Seq(castAs(a0), " & ", castAs(a1))
- case Or => Seq(castAs(a0), " | ", castAs(a1))
- case Xor => Seq(castAs(a0), " ^ ", castAs(a1))
- case Andr => Seq("&", cast(a0))
- case Orr => Seq("|", cast(a0))
- case Xorr => Seq("^", cast(a0))
- case Cat => "{" +: (castCatArgs(a0, a1) :+ "}")
- // If selecting zeroth bit and single-bit wire, just emit the wire
- case Bits if c0 == 0 && c1 == 0 && bitWidth(a0.tpe) == BigInt(1) => Seq(a0)
- case Bits if c0 == c1 => Seq(a0, "[", c0, "]")
- case Bits => Seq(a0, "[", c0, ":", c1, "]")
- // If selecting zeroth bit and single-bit wire, just emit the wire
- case Head if c0 == 1 && bitWidth(a0.tpe) == BigInt(1) => Seq(a0)
- case Head if c0 == 1 => Seq(a0, "[", bitWidth(a0.tpe)-1, "]")
- case Head =>
- val msb = bitWidth(a0.tpe) - 1
- val lsb = bitWidth(a0.tpe) - c0
- Seq(a0, "[", msb, ":", lsb, "]")
- case Tail if c0 == (bitWidth(a0.tpe)-1) => Seq(a0, "[0]")
- case Tail => Seq(a0, "[", bitWidth(a0.tpe) - c0 - 1, ":0]")
- }
- }
+ //;------------- PASS -----------------
+ def v_print(e: Expression)(implicit w: Writer) = e match {
+ case UIntLiteral(value, IntWidth(width)) =>
+ w.write(s"$width'h${value.toString(16)}")
+ case SIntLiteral(value, IntWidth(width)) =>
+ val stringLiteral = value.toString(16)
+ w.write(stringLiteral.head match {
+ case '-' if value == FixAddingNegativeLiterals.minNegValue(width) => s"$width'sh${stringLiteral.tail}"
+ case '-' => s"-$width'sh${stringLiteral.tail}"
+ case _ => s"$width'sh${stringLiteral}"
+ })
+ case _ => throwInternalError(s"attempt to print unrecognized expression: $e")
+ }
+
+ // NOTE: We emit SInts as regular Verilog unsigned wires/regs so the real type of any SInt
+ // reference is actually unsigned in the emitted Verilog. Thus we must cast refs as necessary
+ // to ensure Verilog operations are signed.
+ def op_stream(doprim: DoPrim): Seq[Any] = {
+ // Cast to SInt, don't cast multiple times
+ def doCast(e: Expression): Any = e match {
+ case DoPrim(AsSInt, Seq(arg), _, _) => doCast(arg)
+ case slit: SIntLiteral => slit
+ case other => Seq("$signed(", other, ")")
+ }
+ def castIf(e: Expression): Any = {
+ if (doprim.args.exists(_.tpe.isInstanceOf[SIntType])) {
+ e.tpe match {
+ case _: SIntType => doCast(e)
+ case _ => throwInternalError(s"Unexpected non-SInt type for $e in $doprim")
+ }
+ } else {
+ e
+ }
+ }
+ def cast(e: Expression): Any = doprim.tpe match {
+ case _: UIntType => e
+ case _: SIntType => doCast(e)
+ case _ => throwInternalError(s"Unexpected type for $e in $doprim")
+ }
+ def castAs(e: Expression): Any = e.tpe match {
+ case _: UIntType => e
+ case _: SIntType => doCast(e)
+ case _ => throwInternalError(s"Unexpected type for $e in $doprim")
+ }
+ def a0: Expression = doprim.args.head
+ def a1: Expression = doprim.args(1)
+ def c0: Int = doprim.consts.head.toInt
+ def c1: Int = doprim.consts(1).toInt
+
+ def checkArgumentLegality(e: Expression): Unit = e match {
+ case _: UIntLiteral | _: SIntLiteral | _: WRef | _: WSubField =>
+ case DoPrim(Not, args, _, _) => args.foreach(checkArgumentLegality)
+ case DoPrim(op, args, _, _) if isCast(op) => args.foreach(checkArgumentLegality)
+ case DoPrim(op, args, _, _) if isBitExtract(op) => args.foreach(checkArgumentLegality)
+ case _ => throw EmitterException(s"Can't emit ${e.getClass.getName} as PrimOp argument")
+ }
+
+ def checkCatArgumentLegality(e: Expression): Unit = e match {
+ case DoPrim(Cat, args, _, _) => args.foreach(checkCatArgumentLegality)
+ case _ => checkArgumentLegality(e)
+ }
+
+ def castCatArgs(a0: Expression, a1: Expression): Seq[Any] = {
+ val a0Seq = a0 match {
+ case cat @ DoPrim(PrimOps.Cat, args, _, _) => castCatArgs(args.head, args(1))
+ case _ => Seq(cast(a0))
+ }
+ val a1Seq = a1 match {
+ case cat @ DoPrim(PrimOps.Cat, args, _, _) => castCatArgs(args.head, args(1))
+ case _ => Seq(cast(a1))
+ }
+ a0Seq ++ Seq(",") ++ a1Seq
+ }
+
+ doprim.op match {
+ case Cat => doprim.args.foreach(checkCatArgumentLegality)
+ case cast if isCast(cast) => // Casts are allowed to wrap any Expression
+ case other => doprim.args.foreach(checkArgumentLegality)
+ }
+ doprim.op match {
+ case Add => Seq(castIf(a0), " + ", castIf(a1))
+ case Addw => Seq(castIf(a0), " + ", castIf(a1))
+ case Sub => Seq(castIf(a0), " - ", castIf(a1))
+ case Subw => Seq(castIf(a0), " - ", castIf(a1))
+ case Mul => Seq(castIf(a0), " * ", castIf(a1))
+ case Div => Seq(castIf(a0), " / ", castIf(a1))
+ case Rem => Seq(castIf(a0), " % ", castIf(a1))
+ case Lt => Seq(castIf(a0), " < ", castIf(a1))
+ case Leq => Seq(castIf(a0), " <= ", castIf(a1))
+ case Gt => Seq(castIf(a0), " > ", castIf(a1))
+ case Geq => Seq(castIf(a0), " >= ", castIf(a1))
+ case Eq => Seq(castIf(a0), " == ", castIf(a1))
+ case Neq => Seq(castIf(a0), " != ", castIf(a1))
+ case Pad =>
+ val w = bitWidth(a0.tpe)
+ val diff = c0 - w
+ if (w == BigInt(0) || diff <= 0) Seq(a0)
+ else
+ doprim.tpe match {
+ // Either sign extend or zero extend.
+ // If width == BigInt(1), don't extract bit
+ case (_: SIntType) if w == BigInt(1) => Seq("{", c0, "{", a0, "}}")
+ case (_: SIntType) => Seq("{{", diff, "{", a0, "[", w - 1, "]}},", a0, "}")
+ case (_) => Seq("{{", diff, "'d0}, ", a0, "}")
+ }
+ // Because we don't support complex Expressions, all casts are ignored
+ // This simplifies handling of assignment of a signed expression to an unsigned LHS value
+ // which does not require a cast in Verilog
+ case AsUInt | AsSInt | AsClock | AsAsyncReset => Seq(a0)
+ case Dshlw => Seq(cast(a0), " << ", a1)
+ case Dshl => Seq(cast(a0), " << ", a1)
+ case Dshr =>
+ doprim.tpe match {
+ case (_: SIntType) => Seq(cast(a0), " >>> ", a1)
+ case (_) => Seq(cast(a0), " >> ", a1)
+ }
+ case Shl => if (c0 > 0) Seq("{", cast(a0), s", $c0'h0}") else Seq(cast(a0))
+ case Shr if c0 >= bitWidth(a0.tpe) =>
+ error("Verilog emitter does not support SHIFT_RIGHT >= arg width")
+ case Shr if c0 == (bitWidth(a0.tpe) - 1) => Seq(a0, "[", bitWidth(a0.tpe) - 1, "]")
+ case Shr => Seq(a0, "[", bitWidth(a0.tpe) - 1, ":", c0, "]")
+ case Neg => Seq("-", cast(a0))
+ case Cvt =>
+ a0.tpe match {
+ case (_: UIntType) => Seq("{1'b0,", cast(a0), "}")
+ case (_: SIntType) => Seq(cast(a0))
+ }
+ case Not => Seq("~", a0)
+ case And => Seq(castAs(a0), " & ", castAs(a1))
+ case Or => Seq(castAs(a0), " | ", castAs(a1))
+ case Xor => Seq(castAs(a0), " ^ ", castAs(a1))
+ case Andr => Seq("&", cast(a0))
+ case Orr => Seq("|", cast(a0))
+ case Xorr => Seq("^", cast(a0))
+ case Cat => "{" +: (castCatArgs(a0, a1) :+ "}")
+ // If selecting zeroth bit and single-bit wire, just emit the wire
+ case Bits if c0 == 0 && c1 == 0 && bitWidth(a0.tpe) == BigInt(1) => Seq(a0)
+ case Bits if c0 == c1 => Seq(a0, "[", c0, "]")
+ case Bits => Seq(a0, "[", c0, ":", c1, "]")
+ // If selecting zeroth bit and single-bit wire, just emit the wire
+ case Head if c0 == 1 && bitWidth(a0.tpe) == BigInt(1) => Seq(a0)
+ case Head if c0 == 1 => Seq(a0, "[", bitWidth(a0.tpe) - 1, "]")
+ case Head =>
+ val msb = bitWidth(a0.tpe) - 1
+ val lsb = bitWidth(a0.tpe) - c0
+ Seq(a0, "[", msb, ":", lsb, "]")
+ case Tail if c0 == (bitWidth(a0.tpe) - 1) => Seq(a0, "[0]")
+ case Tail => Seq(a0, "[", bitWidth(a0.tpe) - c0 - 1, ":0]")
+ }
+ }
/**
* Gets a reference to a verilog renderer. This is used by the current standard verilog emission process
@@ -475,31 +508,43 @@ class VerilogEmitter extends SeqTransform with Emitter {
* @param writer where rendering will be placed
* @return the render reference
*/
- def getRenderer(descriptions: Seq[DescriptionAnnotation],
- m: Module,
- moduleMap: Map[String, DefModule])(implicit writer: Writer): VerilogRender = {
+ def getRenderer(
+ descriptions: Seq[DescriptionAnnotation],
+ m: Module,
+ moduleMap: Map[String, DefModule]
+ )(
+ implicit writer: Writer
+ ): VerilogRender = {
val newMod = new AddDescriptionNodes().executeModule(m, descriptions)
newMod match {
- case DescribedMod(d, pds, m: Module) => new VerilogRender(d, pds, m, moduleMap, "", new EmissionOptions(Seq.empty))(writer)
+ case DescribedMod(d, pds, m: Module) =>
+ new VerilogRender(d, pds, m, moduleMap, "", new EmissionOptions(Seq.empty))(writer)
case m: Module => new VerilogRender(m, moduleMap)(writer)
}
}
- def addFormalStatement(formals: mutable.Map[Expression, ArrayBuffer[Seq[Any]]],
- clk: Expression, en: Expression,
- stmt: Seq[Any], info: Info, msg: StringLit): Unit = {
- throw EmitterException("Cannot emit verification statements in Verilog" +
- "(2001). Use the SystemVerilog emitter instead.")
+ def addFormalStatement(
+ formals: mutable.Map[Expression, ArrayBuffer[Seq[Any]]],
+ clk: Expression,
+ en: Expression,
+ stmt: Seq[Any],
+ info: Info,
+ msg: StringLit
+ ): Unit = {
+ throw EmitterException(
+ "Cannot emit verification statements in Verilog" +
+ "(2001). Use the SystemVerilog emitter instead."
+ )
}
/**
* Store Emission option per Target
* Guarantee only one emission option per Target
*/
- private[firrtl] class EmissionOptionMap[V <: EmissionOption](val df : V) {
+ private[firrtl] class EmissionOptionMap[V <: EmissionOption](val df: V) {
private val m = collection.mutable.HashMap[ReferenceTarget, V]().withDefaultValue(df)
- def +=(elem : (ReferenceTarget, V)) : EmissionOptionMap.this.type = {
+ def +=(elem: (ReferenceTarget, V)): EmissionOptionMap.this.type = {
if (m.contains(elem._1))
throw EmitterException(s"Multiple EmissionOption for the target ${elem._1} (${m(elem._1)} ; ${elem._2})")
m += (elem)
@@ -511,7 +556,6 @@ class VerilogEmitter extends SeqTransform with Emitter {
/** Provide API to retrieve EmissionOptions based on the provided [[AnnotationSeq]]
*
* @param annotations : AnnotationSeq to be searched for EmissionOptions
- *
*/
private[firrtl] class EmissionOptions(annotations: AnnotationSeq) {
// Private so that we can present an immutable API
@@ -540,16 +584,34 @@ class VerilogEmitter extends SeqTransform with Emitter {
def getConnectEmissionOption(target: ReferenceTarget): ConnectEmissionOption =
connectEmissionOption(target)
- private val emissionAnnos = annotations.collect{
- case m : SingleTargetAnnotation[ReferenceTarget] @unchecked with EmissionOption => m
+ private val emissionAnnos = annotations.collect {
+ case m: SingleTargetAnnotation[ReferenceTarget] @unchecked with EmissionOption => m
}
// using multiple foreach instead of a single partial function as an Annotation can gather multiple EmissionOptions for simplicity
- emissionAnnos.foreach { case a :MemoryEmissionOption => memoryEmissionOption += ((a.target,a)) case _ => }
- emissionAnnos.foreach { case a :RegisterEmissionOption => registerEmissionOption += ((a.target,a)) case _ => }
- emissionAnnos.foreach { case a :WireEmissionOption => wireEmissionOption += ((a.target,a)) case _ => }
- emissionAnnos.foreach { case a :PortEmissionOption => portEmissionOption += ((a.target,a)) case _ => }
- emissionAnnos.foreach { case a :NodeEmissionOption => nodeEmissionOption += ((a.target,a)) case _ => }
- emissionAnnos.foreach { case a :ConnectEmissionOption => connectEmissionOption += ((a.target,a)) case _ => }
+ emissionAnnos.foreach {
+ case a: MemoryEmissionOption => memoryEmissionOption += ((a.target, a))
+ case _ =>
+ }
+ emissionAnnos.foreach {
+ case a: RegisterEmissionOption => registerEmissionOption += ((a.target, a))
+ case _ =>
+ }
+ emissionAnnos.foreach {
+ case a: WireEmissionOption => wireEmissionOption += ((a.target, a))
+ case _ =>
+ }
+ emissionAnnos.foreach {
+ case a: PortEmissionOption => portEmissionOption += ((a.target, a))
+ case _ =>
+ }
+ emissionAnnos.foreach {
+ case a: NodeEmissionOption => nodeEmissionOption += ((a.target, a))
+ case _ =>
+ }
+ emissionAnnos.foreach {
+ case a: ConnectEmissionOption => connectEmissionOption += ((a.target, a))
+ case _ =>
+ }
}
/**
@@ -562,14 +624,24 @@ class VerilogEmitter extends SeqTransform with Emitter {
* @param moduleMap a map of modules so submodules can be discovered
* @param writer where rendered information is placed.
*/
- class VerilogRender(description: Seq[Description],
- portDescriptions: Map[String, Seq[Description]],
- m: Module,
- moduleMap: Map[String, DefModule],
- circuitName: String,
- emissionOptions: EmissionOptions)(implicit writer: Writer) {
-
- def this(m: Module, moduleMap: Map[String, DefModule], circuitName: String, emissionOptions: EmissionOptions)(implicit writer: Writer) = {
+ class VerilogRender(
+ description: Seq[Description],
+ portDescriptions: Map[String, Seq[Description]],
+ m: Module,
+ moduleMap: Map[String, DefModule],
+ circuitName: String,
+ emissionOptions: EmissionOptions
+ )(
+ implicit writer: Writer) {
+
+ def this(
+ m: Module,
+ moduleMap: Map[String, DefModule],
+ circuitName: String,
+ emissionOptions: EmissionOptions
+ )(
+ implicit writer: Writer
+ ) = {
this(Seq(), Map.empty, m, moduleMap, circuitName, emissionOptions)(writer)
}
def this(m: Module, moduleMap: Map[String, DefModule])(implicit writer: Writer) = {
@@ -582,7 +654,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
def build_netlist(s: Statement): Unit = {
s.foreach(build_netlist)
s match {
- case sx: Connect => netlist(sx.loc) = InfoExpr(sx.info, sx.expr)
+ case sx: Connect => netlist(sx.loc) = InfoExpr(sx.info, sx.expr)
case sx: IsInvalid => error("Should have removed these!")
// TODO Since only register update and memories use the netlist anymore, I think nodes are
// unnecessary
@@ -642,7 +714,14 @@ class VerilogEmitter extends SeqTransform with Emitter {
if (bi.isValidInt) bi.toString else s"${bi.bitLength}'d$bi"
// declare vector type with no preset and optionally with an ifdef guard
- private def declareVectorType(b: String, n: String, tpe: Type, size: BigInt, info: Info, ifdefOpt: Option[String]): Unit = {
+ private def declareVectorType(
+ b: String,
+ n: String,
+ tpe: Type,
+ size: BigInt,
+ info: Info,
+ ifdefOpt: Option[String]
+ ): Unit = {
val decl = Seq(b, " ", tpe, " ", n, " [0:", bigIntToVLit(size - 1), "];", info)
if (ifdefOpt.isDefined) {
ifdefDeclares(ifdefOpt.get) += decl
@@ -675,7 +754,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
case tx: VectorType =>
declareVectorType(b, n, tx.tpe, tx.size, info, ifdefOpt)
case tx =>
- val decl = Seq(b, " ", tx, " ", n,";",info)
+ val decl = Seq(b, " ", tx, " ", n, ";", info)
if (ifdefOpt.isDefined) {
ifdefDeclares(ifdefOpt.get) += decl
} else {
@@ -703,8 +782,18 @@ class VerilogEmitter extends SeqTransform with Emitter {
assigns += Seq("`ifndef RANDOMIZE_GARBAGE_ASSIGN")
assigns += Seq("assign ", e, " = ", syn, ";", info)
assigns += Seq("`else")
- assigns += Seq("assign ", e, " = ", garbageCond, " ? ", rand_string(syn.tpe, "RANDOMIZE_GARBAGE_ASSIGN"), " : ", syn,
- ";", info)
+ assigns += Seq(
+ "assign ",
+ e,
+ " = ",
+ garbageCond,
+ " ? ",
+ rand_string(syn.tpe, "RANDOMIZE_GARBAGE_ASSIGN"),
+ " : ",
+ syn,
+ ";",
+ info
+ )
assigns += Seq("`endif // RANDOMIZE_GARBAGE_ASSIGN")
}
@@ -721,12 +810,12 @@ class VerilogEmitter extends SeqTransform with Emitter {
if (m.tpe == AsyncResetType) throw EmitterException("Cannot emit async reset muxes directly")
val (eninfo, tinfo, finfo) = MultiInfo.demux(info)
- lazy val _if = Seq(tabs, "if (", m.cond, ") begin", eninfo)
- lazy val _else = Seq(tabs, "end else begin")
- lazy val _ifNot = Seq(tabs, "if (!(", m.cond, ")) begin", eninfo)
- lazy val _end = Seq(tabs, "end")
- lazy val _true = addUpdate(tinfo, m.tval, tabs + tab)
- lazy val _false = addUpdate(finfo, m.fval, tabs + tab)
+ lazy val _if = Seq(tabs, "if (", m.cond, ") begin", eninfo)
+ lazy val _else = Seq(tabs, "end else begin")
+ lazy val _ifNot = Seq(tabs, "if (!(", m.cond, ")) begin", eninfo)
+ lazy val _end = Seq(tabs, "end")
+ lazy val _true = addUpdate(tinfo, m.tval, tabs + tab)
+ lazy val _false = addUpdate(finfo, m.fval, tabs + tab)
lazy val _elseIfFalse = {
val _falsex = addUpdate(finfo, m.fval, tabs) // _false, but without an additional tab
Seq(tabs, "end else ", _falsex.head.tail) +: _falsex.tail
@@ -743,13 +832,14 @@ class VerilogEmitter extends SeqTransform with Emitter {
*/
(m.tval, m.fval) match {
case (t, f) if weq(t, r) && weq(f, r) => Nil
- case (t, _) if weq(t, r) => _ifNot +: _false :+ _end
- case (_, f) if weq(f, r) => m.cond.tpe match {
- case AsyncResetType => (_if +: _true :+ _else) ++ _true :+ _end
- case _ => _if +: _true :+ _end
- }
- case (_, _: Mux) => (_if +: _true) ++ _elseIfFalse
- case _ => (_if +: _true :+ _else) ++ _false :+ _end
+ case (t, _) if weq(t, r) => _ifNot +: _false :+ _end
+ case (_, f) if weq(f, r) =>
+ m.cond.tpe match {
+ case AsyncResetType => (_if +: _true :+ _else) ++ _true :+ _end
+ case _ => _if +: _true :+ _end
+ }
+ case (_, _: Mux) => (_if +: _true) ++ _elseIfFalse
+ case _ => (_if +: _true :+ _else) ++ _false :+ _end
}
case e => Seq(Seq(tabs, r, " <= ", e, ";", info))
}
@@ -816,35 +906,52 @@ class VerilogEmitter extends SeqTransform with Emitter {
val maxDataValue = (BigInt(1) << dataWidth.toInt) - 1
def checkValueRange(value: BigInt, at: String): Unit = {
- if(value < 0) throw EmitterException(s"Memory ${at} cannot be initialized with negative value: $value")
- if(value > maxDataValue) throw EmitterException(s"Memory ${at} cannot be initialized with value: $value. Too large (> $maxDataValue)!")
+ if (value < 0) throw EmitterException(s"Memory ${at} cannot be initialized with negative value: $value")
+ if (value > maxDataValue)
+ throw EmitterException(s"Memory ${at} cannot be initialized with value: $value. Too large (> $maxDataValue)!")
}
opt.initValue match {
case MemoryArrayInit(values) =>
- if(values.length != s.depth) throw EmitterException(
- s"Memory ${s.name} of depth ${s.depth} cannot be initialized with an array of length ${values.length}!"
- )
+ if (values.length != s.depth)
+ throw EmitterException(
+ s"Memory ${s.name} of depth ${s.depth} cannot be initialized with an array of length ${values.length}!"
+ )
val memName = LowerTypes.loweredName(wref(s.name, s.dataType))
- values.zipWithIndex.foreach { case (value, addr) =>
- checkValueRange(value, s"${s.name}[$addr]")
- val access = s"$memName[${bigIntToVLit(addr)}]"
- memoryInitials += Seq(access, " = ", bigIntToVLit(value), ";")
+ values.zipWithIndex.foreach {
+ case (value, addr) =>
+ checkValueRange(value, s"${s.name}[$addr]")
+ val access = s"$memName[${bigIntToVLit(addr)}]"
+ memoryInitials += Seq(access, " = ", bigIntToVLit(value), ";")
}
case MemoryScalarInit(value) =>
checkValueRange(value, s.name)
// note: s.dataType is the incorrect type for initvar, but it is ignored in the serialization
val index = wref("initvar", s.dataType)
memoryInitials += Seq("for (initvar = 0; initvar < ", bigIntToVLit(s.depth), "; initvar = initvar+1)")
- memoryInitials += Seq(tab, WSubAccess(wref(s.name, s.dataType), index, s.dataType, SinkFlow),
- " = ", bigIntToVLit(value), ";")
+ memoryInitials += Seq(
+ tab,
+ WSubAccess(wref(s.name, s.dataType), index, s.dataType, SinkFlow),
+ " = ",
+ bigIntToVLit(value),
+ ";"
+ )
case MemoryRandomInit =>
// note: s.dataType is the incorrect type for initvar, but it is ignored in the serialization
val index = wref("initvar", s.dataType)
val rstring = rand_string(s.dataType, "RANDOMIZE_MEM_INIT")
- ifdefInitials("RANDOMIZE_MEM_INIT") += Seq("for (initvar = 0; initvar < ", bigIntToVLit(s.depth), "; initvar = initvar+1)")
- ifdefInitials("RANDOMIZE_MEM_INIT") += Seq(tab, WSubAccess(wref(s.name, s.dataType), index, s.dataType, SinkFlow),
- " = ", rstring, ";")
+ ifdefInitials("RANDOMIZE_MEM_INIT") += Seq(
+ "for (initvar = 0; initvar < ",
+ bigIntToVLit(s.depth),
+ "; initvar = initvar+1)"
+ )
+ ifdefInitials("RANDOMIZE_MEM_INIT") += Seq(
+ tab,
+ WSubAccess(wref(s.name, s.dataType), index, s.dataType, SinkFlow),
+ " = ",
+ rstring,
+ ";"
+ )
}
}
@@ -888,7 +995,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
if (lines.size > 1) {
val lineSeqs = lines.tail.map {
- case "" => Seq(" *")
+ case "" => Seq(" *")
case nonEmpty => Seq(" * ", nonEmpty)
}
Seq("/* ", lines.head) +: lineSeqs :+ Seq(" */")
@@ -905,19 +1012,20 @@ class VerilogEmitter extends SeqTransform with Emitter {
def build_ports(): Unit = {
def padToMax(strs: Seq[String]): Seq[String] = {
val len = if (strs.nonEmpty) strs.map(_.length).max else 0
- strs map (_.padTo(len, ' '))
+ strs.map(_.padTo(len, ' '))
}
// Turn directions into strings (and AnalogType into inout)
- val dirs = m.ports map { case Port(_, name, dir, tpe) =>
- (dir, tpe) match {
- case (_, AnalogType(_)) => "inout " // padded to length of output
- case (Input, _) => "input "
- case (Output, _) => "output"
- }
+ val dirs = m.ports.map {
+ case Port(_, name, dir, tpe) =>
+ (dir, tpe) match {
+ case (_, AnalogType(_)) => "inout " // padded to length of output
+ case (Input, _) => "input "
+ case (Output, _) => "output"
+ }
}
// Turn types into strings, all ports must be GroundTypes
- val tpes = m.ports map {
+ val tpes = m.ports.map {
case Port(_, _, _, tpe: GroundType) => stringify(tpe)
case port: Port => error(s"Trying to emit non-GroundType Port $port")
}
@@ -925,9 +1033,10 @@ class VerilogEmitter extends SeqTransform with Emitter {
// dirs are already padded
(dirs, padToMax(tpes), m.ports).zipped.toSeq.zipWithIndex.foreach {
case ((dir, tpe, Port(info, name, _, _)), i) =>
- portDescriptions.get(name).map { case d =>
- portdefs += Seq("")
- portdefs ++= build_description(d)
+ portDescriptions.get(name).map {
+ case d =>
+ portdefs += Seq("")
+ portdefs ++= build_description(d)
}
if (i != m.ports.size - 1) {
@@ -956,14 +1065,14 @@ class VerilogEmitter extends SeqTransform with Emitter {
}
withoutDescription.foreach(build_streams)
withoutDescription match {
- case sx@Connect(info, loc@WRef(_, _, PortKind | WireKind | InstanceKind, _), expr) =>
+ case sx @ Connect(info, loc @ WRef(_, _, PortKind | WireKind | InstanceKind, _), expr) =>
assign(loc, expr, info)
case sx: DefWire =>
declare("wire", sx.name, sx.tpe, sx.info)
case sx: DefRegister =>
val options = emissionOptions.getRegisterEmissionOption(moduleTarget.ref(sx.name))
val e = wref(sx.name, sx.tpe)
- if (options.useInitAsPreset){
+ if (options.useInitAsPreset) {
declare("reg", sx.name, sx.tpe, sx.info, sx.init)
regUpdate(e, sx.clock, sx.reset, e)
} else {
@@ -997,11 +1106,11 @@ class VerilogEmitter extends SeqTransform with Emitter {
case sx: WDefInstanceConnector =>
val (module, params) = moduleMap(sx.module) match {
case DescribedMod(_, _, ExtModule(_, _, _, extname, params)) => (extname, params)
- case DescribedMod(_, _, Module(_, name, _, _)) => (name, Seq.empty)
- case ExtModule(_, _, _, extname, params) => (extname, params)
- case Module(_, name, _, _) => (name, Seq.empty)
+ case DescribedMod(_, _, Module(_, name, _, _)) => (name, Seq.empty)
+ case ExtModule(_, _, _, extname, params) => (extname, params)
+ case Module(_, name, _, _) => (name, Seq.empty)
}
- val ps = if (params.nonEmpty) params map stringify mkString("#(", ", ", ") ") else ""
+ val ps = if (params.nonEmpty) params.map(stringify).mkString("#(", ", ", ") ") else ""
instdeclares += Seq(module, " ", ps, sx.name, " (", sx.info)
for (((port, ref), i) <- sx.portCons.zipWithIndex) {
val line = Seq(tab, ".", remove_root(port), "(", ref, ")")
@@ -1012,14 +1121,16 @@ class VerilogEmitter extends SeqTransform with Emitter {
case sx: DefMemory =>
val options = emissionOptions.getMemoryEmissionOption(moduleTarget.ref(sx.name))
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, options)
if (sx.readLatency != 0 || sx.writeLatency != 1)
- throw EmitterException("All memories should be transformed into " +
- "blackboxes or combinational by previous passses")
+ throw EmitterException(
+ "All memories should be transformed into " +
+ "blackboxes or combinational by previous passses"
+ )
for (r <- sx.readers) {
val data = memPortField(sx, r, "data")
val addr = memPortField(sx, r, "addr")
@@ -1031,7 +1142,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
//; Read port
assign(addr, netlist(addr))
- // 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, UnknownFlow)
val memPort = WSubAccess(mem, addr, sx.dataType, UnknownFlow)
val depthValue = UIntLiteral(sx.depth, IntWidth(sx.depth.bitLength))
@@ -1069,8 +1180,10 @@ 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")
+ throw EmitterException(
+ "All readwrite ports should be transformed into " +
+ "read & write ports by previous passes"
+ )
case _ =>
}
}
@@ -1081,10 +1194,11 @@ class VerilogEmitter extends SeqTransform with Emitter {
for (x <- portdefs) emit(Seq(tab, x))
emit(Seq(");"))
- ifdefDeclares.toSeq.sortWith(_._1 < _._1).foreach { case (ifdef, declares) =>
- emit(Seq("`ifdef " + ifdef))
- for (x <- declares) emit(Seq(tab, x))
- emit(Seq("`endif // " + ifdef))
+ ifdefDeclares.toSeq.sortWith(_._1 < _._1).foreach {
+ case (ifdef, declares) =>
+ emit(Seq("`ifdef " + ifdef))
+ for (x <- declares) emit(Seq(tab, x))
+ emit(Seq("`endif // " + ifdef))
}
for (x <- declares) emit(Seq(tab, x))
for (x <- instdeclares) emit(Seq(tab, x))
@@ -1093,7 +1207,12 @@ class VerilogEmitter extends SeqTransform with Emitter {
emit(Seq("`ifdef SYNTHESIS"))
for (x <- attachSynAssigns) emit(Seq(tab, x))
emit(Seq("`elsif verilator"))
- emit(Seq(tab, "`error \"Verilator does not support alias and thus cannot arbirarily connect bidirectional wires and ports\""))
+ emit(
+ Seq(
+ tab,
+ "`error \"Verilator does not support alias and thus cannot arbirarily connect bidirectional wires and ports\""
+ )
+ )
emit(Seq("`else"))
for (x <- attachAliases) emit(Seq(tab, x))
emit(Seq("`endif"))
@@ -1129,7 +1248,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
emit(Seq("`define RANDOM $random"))
emit(Seq("`endif"))
// the initvar is also used to initialize memories to constants
- if(memoryInitials.isEmpty) emit(Seq("`ifdef RANDOMIZE_MEM_INIT"))
+ if (memoryInitials.isEmpty) emit(Seq("`ifdef RANDOMIZE_MEM_INIT"))
// Since simulators don't actually support memories larger than 2^31 - 1, there is no reason
// to change Verilog emission in the common case. Instead, we only emit a larger initvar
// where necessary
@@ -1140,7 +1259,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
val width = maxMemSize.bitLength - 1 // minus one because [width-1:0] has a width of "width"
emit(Seq(s" reg [$width:0] initvar;"))
}
- if(memoryInitials.isEmpty) emit(Seq("`endif"))
+ if (memoryInitials.isEmpty) emit(Seq("`endif"))
emit(Seq("`ifndef SYNTHESIS"))
// User-defined macro of code to run before an initial block
emit(Seq("`ifdef FIRRTL_BEFORE_INITIAL"))
@@ -1162,15 +1281,16 @@ class VerilogEmitter extends SeqTransform with Emitter {
emit(Seq(" #0.002 begin end"))
emit(Seq(" `endif"))
emit(Seq(" `endif"))
- ifdefInitials.toSeq.sortWith(_._1 < _._1).foreach { case (ifdef, initials) =>
- emit(Seq("`ifdef " + ifdef))
- for (x <- initials) emit(Seq(tab, x))
- emit(Seq("`endif // " + ifdef))
+ ifdefInitials.toSeq.sortWith(_._1 < _._1).foreach {
+ case (ifdef, initials) =>
+ emit(Seq("`ifdef " + ifdef))
+ for (x <- initials) emit(Seq(tab, x))
+ emit(Seq("`endif // " + ifdef))
}
for (x <- initials) emit(Seq(tab, x))
for (x <- asyncInitials) emit(Seq(tab, x))
emit(Seq(" `endif // RANDOMIZE"))
- for(x <- memoryInitials) emit(Seq(tab, x))
+ for (x <- memoryInitials) emit(Seq(tab, x))
emit(Seq("end // initial"))
// User-defined macro of code to run after an initial block
emit(Seq("`ifdef FIRRTL_AFTER_INITIAL"))
@@ -1258,7 +1378,7 @@ class VerilogEmitter extends SeqTransform with Emitter {
val emissionOptions = new EmissionOptions(cs.annotations)
val moduleMap = cs.circuit.modules.map(m => m.name -> m).toMap
- cs.circuit.modules flatMap {
+ cs.circuit.modules.flatMap {
case dm @ DescribedMod(d, pds, module: Module) =>
val writer = new java.io.StringWriter
val renderer = new VerilogRender(d, pds, module, moduleMap, cs.circuit.main, emissionOptions)(writer)
@@ -1282,8 +1402,8 @@ class MinimumVerilogEmitter extends VerilogEmitter with Emitter {
override def prerequisites = firrtl.stage.Forms.AssertsRemoved ++
firrtl.stage.Forms.LowFormMinimumOptimized
- override def transforms = new TransformManager(firrtl.stage.Forms.VerilogMinimumOptimized, prerequisites)
- .flattenedTransformOrder
+ override def transforms =
+ new TransformManager(firrtl.stage.Forms.VerilogMinimumOptimized, prerequisites).flattenedTransformOrder
}
@@ -1292,9 +1412,14 @@ class SystemVerilogEmitter extends VerilogEmitter {
override def prerequisites = firrtl.stage.Forms.LowFormOptimized
- override def addFormalStatement(formals: mutable.Map[Expression, ArrayBuffer[Seq[Any]]],
- clk: Expression, en: Expression,
- stmt: Seq[Any], info: Info, msg: StringLit): Unit = {
+ override def addFormalStatement(
+ formals: mutable.Map[Expression, ArrayBuffer[Seq[Any]]],
+ clk: Expression,
+ en: Expression,
+ stmt: Seq[Any],
+ info: Info,
+ msg: StringLit
+ ): Unit = {
val lines = formals.getOrElseUpdate(clk, ArrayBuffer[Seq[Any]]())
lines += Seq("// ", msg.serialize)
lines += Seq("if (", en, ") begin")