summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/chisel3/internal')
-rw-r--r--src/main/scala/chisel3/internal/firrtl/Emitter.scala49
1 files changed, 42 insertions, 7 deletions
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
index 16b39e35..593052c7 100644
--- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala
+++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
@@ -2,6 +2,7 @@
package chisel3.internal.firrtl
import chisel3._
+import chisel3.core.UserDirection
import chisel3.experimental._
import chisel3.internal.sourceinfo.{NoSourceInfo, SourceLine}
@@ -12,16 +13,50 @@ private[chisel3] object Emitter {
private class Emitter(circuit: Circuit) {
override def toString: String = res.toString
- private def emitPort(e: Port): String =
- s"${e.dir} ${e.id.getRef.name} : ${e.id.toType}"
+ private def emitPort(e: Port): String = {
+ val dir = e.dir match {
+ case UserDirection.Unspecified | UserDirection.Output => "output"
+ case UserDirection.Flip | UserDirection.Input => "input"
+ }
+ s"$dir ${e.id.getRef.name} : ${emitType(e.id)}"
+ }
+
+ private def emitType(d: Data, clearDir: Boolean = false): String = d match {
+ case d: Clock => "Clock"
+ case d: UInt => s"UInt${d.width}"
+ case d: SInt => s"SInt${d.width}"
+ case d: FixedPoint => s"Fixed${d.width}${d.binaryPoint}"
+ case d: Analog => s"Analog${d.width}"
+ case d: Vec[_] => s"${emitType(d.sample_element, clearDir)}[${d.length}]"
+ case d: Record => {
+ val childClearDir = clearDir ||
+ d.userDirection == UserDirection.Input || d.userDirection == UserDirection.Output
+ def eltPort(elt: Data): String = (childClearDir, firrtlUserDirOf(elt)) match {
+ case (true, _) =>
+ s"${elt.getRef.name} : ${emitType(elt, true)}"
+ case (false, UserDirection.Unspecified | UserDirection.Output) =>
+ s"${elt.getRef.name} : ${emitType(elt, false)}"
+ case (false, UserDirection.Flip | UserDirection.Input) =>
+ s"flip ${elt.getRef.name} : ${emitType(elt, false)}"
+ }
+ d.elements.toIndexedSeq.reverse.map(e => eltPort(e._2)).mkString("{", ", ", "}")
+ }
+ }
+
+ private def firrtlUserDirOf(d: Data): UserDirection = d match {
+ case d: Vec[_] =>
+ UserDirection.fromParent(d.userDirection, firrtlUserDirOf(d.sample_element))
+ case d => d.userDirection
+ }
+
private def emit(e: Command, ctx: Component): String = {
val firrtlLine = e match {
case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${e.args.map(_.fullName(ctx)).mkString(", ")})"
- case e: DefWire => s"wire ${e.name} : ${e.id.toType}"
- case e: DefReg => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}"
- case e: DefRegInit => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))"
- case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]"
- case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}]"
+ case e: DefWire => s"wire ${e.name} : ${emitType(e.id)}"
+ case e: DefReg => s"reg ${e.name} : ${emitType(e.id)}, ${e.clock.fullName(ctx)}"
+ case e: DefRegInit => s"reg ${e.name} : ${emitType(e.id)}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))"
+ case e: DefMemory => s"cmem ${e.name} : ${emitType(e.t)}[${e.size}]"
+ case e: DefSeqMemory => s"smem ${e.name} : ${emitType(e.t)}[${e.size}]"
case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}"
case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}"
case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}"