diff options
| author | Andrew Waterman | 2016-01-28 12:15:53 -0800 |
|---|---|---|
| committer | Andrew Waterman | 2016-01-28 12:15:53 -0800 |
| commit | 7eff2b0a16e1ca982c227bd498720981c883686b (patch) | |
| tree | 767a04718b16750b33dd4e2d629d3e836bb7f637 /src/main/scala/Chisel/internal/firrtl/Emitter.scala | |
| parent | 6d37cc8b9d731fa4c844f097b11057c46771961b (diff) | |
| parent | 41674d5e130f64d7489fdb8583b8f4ad88b64aeb (diff) | |
Merge branch 'master' into scalastyle
Diffstat (limited to 'src/main/scala/Chisel/internal/firrtl/Emitter.scala')
| -rw-r--r-- | src/main/scala/Chisel/internal/firrtl/Emitter.scala | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala new file mode 100644 index 00000000..13d9fa8f --- /dev/null +++ b/src/main/scala/Chisel/internal/firrtl/Emitter.scala @@ -0,0 +1,73 @@ +// See LICENSE for license details. + +package Chisel.internal.firrtl +import Chisel._ + +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 emit(e: Command, ctx: Component): String = e match { + case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${e.args.map(_.fullName(ctx)).reduce(_ + ", " + _)})" + 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: 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)}" + case e: Stop => s"stop(${e.clk.fullName(ctx)}, UInt<1>(1), ${e.ret})" + case e: Printf => s"""printf(${e.clk.fullName(ctx)}, UInt<1>(1), "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})""" + case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid" + case e: DefInstance => { + val modName = moduleMap.getOrElse(e.id.name, e.id.name) + s"inst ${e.name} of $modName" + } + + case w: WhenBegin => + indent() + s"when ${w.pred.fullName(ctx)} :" + case _: WhenEnd => + unindent() + "skip" + } + private def emitBody(m: Component) = { + val me = new StringBuilder + withIndent { + for (p <- m.ports) + me ++= newline + emitPort(p) + me ++= newline + for (cmd <- m.commands) + me ++= newline + emit(cmd, m) + me ++= newline + } + me + } + + private val bodyMap = collection.mutable.HashMap[StringBuilder, String]() + private val moduleMap = collection.mutable.HashMap[String, String]() + + private def emit(m: Component): String = { + val body = emitBody(m) + bodyMap get body match { + case Some(name) => + moduleMap(m.name) = name + "" + case None => + bodyMap(body) = m.name + newline + s"module ${m.name} : " + body + } + } + + 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(c => res ++= emit(c)) } + res ++= newline +} |
