aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-04-27 13:30:59 -0700
committerjackkoenig2016-05-10 14:44:52 -0700
commite78b2b277a93d7d635036da559def6189a2047a2 (patch)
treef251618029a28efaeae33a5aa7e5a522fa8ab990 /src
parent4e784786622496a4447513f1b17dd2ed13fa3e01 (diff)
Added new (and correct) Split Expressions pass
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/passes/SplitExpressions.scala65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/passes/SplitExpressions.scala b/src/main/scala/firrtl/passes/SplitExpressions.scala
new file mode 100644
index 00000000..a66f7152
--- /dev/null
+++ b/src/main/scala/firrtl/passes/SplitExpressions.scala
@@ -0,0 +1,65 @@
+package firrtl
+package passes
+
+import firrtl.Mappers.{ExpMap, StmtMap}
+import firrtl.Utils.{tpe, kind, gender, info}
+import scala.collection.mutable
+
+
+// Splits compound expressions into simple expressions
+// and named intermediate nodes
+object SplitExpressions extends Pass {
+ def name = "Split Expressions"
+ private def onModule(m: InModule): InModule = {
+ val namespace = Namespace(m)
+ def onStmt(s: Stmt): Stmt = {
+ val v = mutable.ArrayBuffer[Stmt]()
+ // Splits current expression if needed
+ // Adds named temporaries to v
+ def split(e: Expression): Expression = e match {
+ case e: DoPrim => {
+ val name = namespace.newTemp
+ v += DefNode(info(s), name, e)
+ WRef(name, tpe(e), kind(e), gender(e))
+ }
+ case e: Mux => {
+ val name = namespace.newTemp
+ v += DefNode(info(s), name, e)
+ WRef(name, tpe(e), kind(e), gender(e))
+ }
+ case e: ValidIf => {
+ val name = namespace.newTemp
+ v += DefNode(info(s), name, e)
+ WRef(name, tpe(e), kind(e), gender(e))
+ }
+ case e => e
+ }
+ // Recursive. Splits compound nodes
+ def onExp(e: Expression): Expression = {
+ val ex = e map onExp
+ ex match {
+ case (_: DoPrim) => ex map split
+ case v => v
+ }
+ }
+ val x = s map onExp
+ x match {
+ case x: Begin => x map onStmt
+ case x: Empty => x
+ case x => {
+ v += x
+ if (v.size > 1) Begin(v.toVector)
+ else v(0)
+ }
+ }
+ }
+ InModule(m.info, m.name, m.ports, onStmt(m.body))
+ }
+ def run(c: Circuit): Circuit = {
+ val modulesx = c.modules.map( _ match {
+ case (m:InModule) => onModule(m)
+ case (m:ExModule) => m
+ })
+ Circuit(c.info, modulesx, c.main)
+ }
+}