diff options
| author | Albert Magyar | 2017-08-17 17:55:44 -0700 |
|---|---|---|
| committer | Jack Koenig | 2017-08-17 17:55:44 -0700 |
| commit | 6297e00aa845cf6cc1275c05d313f3237e69de9d (patch) | |
| tree | 05363bfee404a441d5a759e292bd894c1e2db8a6 /src/main | |
| parent | 6e12ed9fd7a771eb30f44b8e1c4ab33f6ad8e0a6 (diff) | |
Use firrtl elses in elsewhen/otherwise case emission (#510)
Preprocess chisel3 IR before emission to determing whether
whens have alternatives.
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/chisel3/internal/firrtl/Emitter.scala | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 963a713b..09984722 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -75,10 +75,21 @@ private class Emitter(circuit: Circuit) { case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid" case e: DefInstance => s"inst ${e.name} of ${e.id.name}" case w: WhenBegin => + // When consequences are always indented indent() s"when ${w.pred.fullName(ctx)} :" - case _: WhenEnd => + case w: WhenEnd => + // If a when has no else, the indent level must be reset to the enclosing block unindent() + if (!w.hasAlt) { for (i <- 0 until w.firrtlDepth) { unindent() } } + s"skip" + case a: AltBegin => + // Else blocks are always indented + indent() + s"else :" + case o: OtherwiseEnd => + // Chisel otherwise: ends all FIRRTL associated a Chisel when, resetting indent level + for (i <- 0 until o.firrtlDepth) { unindent() } s"skip" } firrtlLine + e.sourceInfo.makeMessage(" " + _) @@ -120,8 +131,10 @@ private class Emitter(circuit: Circuit) { // Firrtl extmodule can overrule name body ++= newline + s"defname = ${bb.id.desiredName}" body ++= newline + (bb.params map { case (n, p) => emitParam(n, p) } mkString newline) - case mod: DefModule => for (cmd <- mod.commands) { - body ++= newline + emit(cmd, mod) + case mod: DefModule => { + // Preprocess whens & elsewhens, marking those that have no alternative + val procMod = mod.copy(commands = processWhens(mod.commands)) + for (cmd <- procMod.commands) { body ++= newline + emit(cmd, procMod)} } } body ++= newline @@ -141,6 +154,16 @@ private class Emitter(circuit: Circuit) { sb.result } + /** Preprocess the command queue, marking when/elsewhen statements + * that have no alternatives (elsewhens or otherwise). These + * alternative-free statements reset the indent level to the + * enclosing block upon emission. + */ + private def processWhens(cmds: Seq[Command]): + Seq[Command] = { cmds.zip(cmds.tail).map({ case (a: WhenEnd, b: + AltBegin) => a.copy(hasAlt = true) case (a, b) => a }) ++ + cmds.lastOption } + private var indentLevel = 0 private def newline = "\n" + (" " * indentLevel) private def indent(): Unit = indentLevel += 1 |
