aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/transforms/RemoveWires.scala
diff options
context:
space:
mode:
authorJack Koenig2019-02-14 15:08:35 -0800
committerGitHub2019-02-14 15:08:35 -0800
commit2272044c6ab46b5148c39c124e66e1a8e9073a24 (patch)
tree83ad2141b1a3c54707dd9b33073f9217b0ae16c8 /src/main/scala/firrtl/transforms/RemoveWires.scala
parentd487b4cb6726e7e8d1a18f894021652594125221 (diff)
Asynchronous Reset (#1011)
Fixes #219 * Adds AsyncResetType (similar to ClockType) * Registers with reset signal of type AsyncResetType are async reset registers * Registers with async reset can only be reset to literal values * Add initialization logic for async reset registers
Diffstat (limited to 'src/main/scala/firrtl/transforms/RemoveWires.scala')
-rw-r--r--src/main/scala/firrtl/transforms/RemoveWires.scala36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/main/scala/firrtl/transforms/RemoveWires.scala b/src/main/scala/firrtl/transforms/RemoveWires.scala
index 1b5b3e5f..da79be8e 100644
--- a/src/main/scala/firrtl/transforms/RemoveWires.scala
+++ b/src/main/scala/firrtl/transforms/RemoveWires.scala
@@ -6,6 +6,7 @@ package transforms
import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
+import firrtl.traversals.Foreachers._
import firrtl.WrappedExpression._
import firrtl.graph.{DiGraph, MutableDiGraph, CyclicException}
@@ -29,7 +30,7 @@ class RemoveWires extends Transform {
def rec(e: Expression): Expression = {
e match {
case ref @ WRef(_,_, WireKind | NodeKind | RegKind, _) => refs += ref
- case nested @ (_: Mux | _: DoPrim | _: ValidIf) => nested map rec
+ case nested @ (_: Mux | _: DoPrim | _: ValidIf) => nested.foreach(rec)
case _ => // Do nothing
}
e
@@ -40,13 +41,15 @@ class RemoveWires extends Transform {
// Transform netlist into DefNodes
private def getOrderedNodes(
- netlist: mutable.LinkedHashMap[WrappedExpression, (Expression, Info)],
+ netlist: mutable.LinkedHashMap[WrappedExpression, (Seq[Expression], Info)],
regInfo: mutable.Map[WrappedExpression, DefRegister]): Try[Seq[Statement]] = {
val digraph = new MutableDiGraph[WrappedExpression]
- for ((sink, (expr, _)) <- netlist) {
+ for ((sink, (exprs, _)) <- netlist) {
digraph.addVertex(sink)
- for (source <- extractNodeWireRegRefs(expr)) {
- digraph.addPairWithEdge(sink, source)
+ for (expr <- exprs) {
+ for (source <- extractNodeWireRegRefs(expr)) {
+ digraph.addPairWithEdge(sink, source)
+ }
}
}
@@ -57,10 +60,11 @@ class RemoveWires extends Transform {
val ordered = digraph.linearize.reverse
ordered.map { key =>
val WRef(name, _, kind, _) = key.e1
- val (rhs, info) = netlist(key)
kind match {
case RegKind => regInfo(key)
- case WireKind | NodeKind => DefNode(info, name, rhs)
+ case WireKind | NodeKind =>
+ val (Seq(rhs), info) = netlist(key)
+ DefNode(info, name, rhs)
}
}
}
@@ -72,7 +76,7 @@ class RemoveWires extends Transform {
// Store all "other" statements here, non-wire, non-node connections, printfs, etc.
val otherStmts = mutable.ArrayBuffer.empty[Statement]
// Add nodes and wire connection here
- val netlist = mutable.LinkedHashMap.empty[WrappedExpression, (Expression, Info)]
+ val netlist = mutable.LinkedHashMap.empty[WrappedExpression, (Seq[Expression], Info)]
// Info at definition of wires for combining into node
val wireInfo = mutable.HashMap.empty[WrappedExpression, Info]
// Additional info about registers
@@ -81,12 +85,16 @@ class RemoveWires extends Transform {
def onStmt(stmt: Statement): Statement = {
stmt match {
case node: DefNode =>
- netlist(we(WRef(node))) = (node.value, node.info)
+ netlist(we(WRef(node))) = (Seq(node.value), node.info)
case wire: DefWire if !wire.tpe.isInstanceOf[AnalogType] => // Remove all non-Analog wires
wireInfo(WRef(wire)) = wire.info
case reg: DefRegister =>
+ val resetDep = reg.reset.tpe match {
+ case AsyncResetType => reg.reset :: Nil
+ case _ => Nil
+ }
regInfo(we(WRef(reg))) = reg
- netlist(we(WRef(reg))) = (reg.clock, reg.info)
+ netlist(we(WRef(reg))) = (reg.clock :: resetDep, reg.info)
case decl: IsDeclaration => // Keep all declarations except for nodes and non-Analog wires
decls += decl
case con @ Connect(cinfo, lhs, rhs) => kind(lhs) match {
@@ -94,20 +102,20 @@ class RemoveWires extends Transform {
// Be sure to pad the rhs since nodes get their type from the rhs
val paddedRhs = ConstantPropagation.pad(rhs, lhs.tpe)
val dinfo = wireInfo(lhs)
- netlist(we(lhs)) = (paddedRhs, MultiInfo(dinfo, cinfo))
+ netlist(we(lhs)) = (Seq(paddedRhs), MultiInfo(dinfo, cinfo))
case _ => otherStmts += con // Other connections just pass through
}
case invalid @ IsInvalid(info, expr) =>
kind(expr) match {
case WireKind =>
val width = expr.tpe match { case GroundType(width) => width } // LowFirrtl
- netlist(we(expr)) = (ValidIf(Utils.zero, UIntLiteral(BigInt(0), width), expr.tpe), info)
+ netlist(we(expr)) = (Seq(ValidIf(Utils.zero, UIntLiteral(BigInt(0), width), expr.tpe)), info)
case _ => otherStmts += invalid
}
case other @ (_: Print | _: Stop | _: Attach) =>
otherStmts += other
case EmptyStmt => // Dont bother keeping EmptyStmts around
- case block: Block => block map onStmt
+ case block: Block => block.foreach(onStmt)
case _ => throwInternalError()
}
stmt
@@ -136,7 +144,7 @@ class RemoveWires extends Transform {
)
def execute(state: CircuitState): CircuitState = {
- val result = state.copy(circuit = state.circuit map onModule)
+ val result = state.copy(circuit = state.circuit.map(onModule))
cleanup.foldLeft(result) { case (in, xform) => xform.execute(in) }
}
}