summaryrefslogtreecommitdiff
path: root/src/main/scala/Chisel/Emitter.scala
diff options
context:
space:
mode:
authorHenry Cook2015-08-13 01:14:55 -0700
committerHenry Cook2015-08-13 01:14:55 -0700
commit976ff1439f51afc08c61ff39ecf0ad2e71a88e2a (patch)
treece77dd94dd84fc024efc372fa444b712aea8c974 /src/main/scala/Chisel/Emitter.scala
parent85d7403f9bf7bc2b3520f924736c237f21f70ebd (diff)
Streamline files, breaking up Core.scala and resorting some smaller ones
Diffstat (limited to 'src/main/scala/Chisel/Emitter.scala')
-rw-r--r--src/main/scala/Chisel/Emitter.scala80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/main/scala/Chisel/Emitter.scala b/src/main/scala/Chisel/Emitter.scala
new file mode 100644
index 00000000..0e75c9a9
--- /dev/null
+++ b/src/main/scala/Chisel/Emitter.scala
@@ -0,0 +1,80 @@
+package Chisel
+
+class Emitter(circuit: Circuit) {
+ override def toString = res.toString
+
+ def join(parts: Seq[String], sep: String): StringBuilder =
+ parts.tail.foldLeft(new StringBuilder(parts.head))((s, p) => s ++= sep ++= p)
+ def emitDir(e: Port, isTop: Boolean): String =
+ if (isTop) (if (e.id.isFlip) "input " else "output ")
+ else (if (e.id.isFlip) "flip " else "")
+ def emitPort(e: Port, isTop: Boolean): String =
+ s"${emitDir(e, isTop)}${circuit.refMap(e.id).name} : ${emitType(e.kind)}"
+ private def emitType(e: Kind): String = e match {
+ case e: UnknownType => "?"
+ case e: UIntType => s"UInt<${e.width}>"
+ case e: SIntType => s"SInt<${e.width}>"
+ case e: BundleType => s"{${join(e.ports.map(x => emitPort(x, false)), ", ")}}"
+ case e: VectorType => s"${emitType(e.kind)}[${e.size}]"
+ case e: ClockType => s"Clock"
+ }
+ private def emit(e: Command, ctx: Component): String = e match {
+ case e: DefFlo => s"node ${e.name} = Flo(${e.value})"
+ case e: DefDbl => s"node ${e.name} = Dbl(${e.value})"
+ case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${join(e.args.map(x => x.fullName(ctx)), ", ")})"
+ case e: DefWire => s"wire ${e.name} : ${emitType(e.kind)}"
+ case e: DefRegister => s"reg ${e.name} : ${emitType(e.kind)}, ${e.clock.fullName(ctx)}, ${e.reset.fullName(ctx)}"
+ case e: DefMemory => s"cmem ${e.name} : ${emitType(e.kind)}[${e.size}], ${e.clock.fullName(ctx)}";
+ case e: DefSeqMemory => s"smem ${e.name} : ${emitType(e.kind)}[${e.size}]";
+ case e: DefAccessor => s"infer accessor ${e.name} = ${e.source.fullName(ctx)}[${e.index.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)}"
+ case e: ConnectInit => s"onreset ${e.loc.fullName(ctx)} := ${e.exp.fullName(ctx)}"
+ case e: DefInstance => {
+ val res = new StringBuilder(s"inst ${e.name} of ${e.id.name}")
+ res ++= newline
+ for (p <- e.ports; x <- initPort(p, INPUT, ctx))
+ res ++= newline + x
+ res.toString
+ }
+
+ case w: WhenBegin =>
+ indent()
+ s"when ${w.pred.fullName(ctx)} :"
+ case _: WhenElse =>
+ indent()
+ "else :"
+ case _: WhenEnd =>
+ unindent()
+ "skip"
+ }
+ private def initPort(p: Port, dir: Direction, ctx: Component) = {
+ for (x <- p.id.flatten; if x.dir == dir)
+ yield s"${circuit.refMap(x).fullName(ctx)} := ${x.makeLit(0).name}"
+ }
+
+ private def emit(m: Component): Unit = {
+ res ++= newline + s"module ${m.name} : "
+ withIndent {
+ for (p <- m.ports)
+ res ++= newline + emitPort(p, true)
+ res ++= newline
+ for (p <- m.ports; x <- initPort(p, OUTPUT, m))
+ res ++= newline + x
+ res ++= newline
+ for (cmd <- m.commands)
+ res ++= newline + emit(cmd, m)
+ res ++= newline
+ }
+ }
+
+ private var indentLevel = 0
+ private def newline = "\n" + (" " * indentLevel)
+ private def indent(): Unit = indentLevel += 1
+ private def unindent() { require(indentLevel > 0); indentLevel -= 1 }
+ private def withIndent(f: => Unit) { indent(); f; unindent() }
+
+ private val res = new StringBuilder(s"circuit ${circuit.name} : ")
+ withIndent { circuit.components foreach emit }
+ res ++= newline
+}