diff options
Diffstat (limited to 'src/main/scala/chisel3/internal')
| -rw-r--r-- | src/main/scala/chisel3/internal/firrtl/Emitter.scala | 49 |
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)}" |
