diff options
| author | Henry Cook | 2015-08-13 01:14:55 -0700 |
|---|---|---|
| committer | Henry Cook | 2015-08-13 01:14:55 -0700 |
| commit | 976ff1439f51afc08c61ff39ecf0ad2e71a88e2a (patch) | |
| tree | ce77dd94dd84fc024efc372fa444b712aea8c974 /src/main/scala/Chisel/Emitter.scala | |
| parent | 85d7403f9bf7bc2b3520f924736c237f21f70ebd (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.scala | 80 |
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 +} |
