aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorJack Koenig2022-04-21 20:20:47 -0700
committerGitHub2022-04-21 20:20:47 -0700
commit5093da03083a37a0a7bdaf44f9867d7f7a0a5980 (patch)
tree25e3d723a95cac8a6cb109e14a28e3df039d467e /src/main
parent410f030dc98177ffe54632c1e25fca873b7b1faf (diff)
Fix optimization of register with reset but invalid connection (#2520)
Fixes #2516 Previously, reg r : UInt<8>, clock with : reset => (p, UInt<8>(3)) r is invalid would compile to: reg r : UInt<8>, clock r <= UInt<8>(0) now it compiles to: reg r : UInt<8>, clock wire r_1 : UInt<8> r_1 is invalid r <= mux(reset, UInt<8>(3), r_1) This is consistent with the behavior for a reset with an asynchronous reset.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/transforms/RemoveReset.scala12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/transforms/RemoveReset.scala b/src/main/scala/firrtl/transforms/RemoveReset.scala
index f1434ad2..7f2207af 100644
--- a/src/main/scala/firrtl/transforms/RemoveReset.scala
+++ b/src/main/scala/firrtl/transforms/RemoveReset.scala
@@ -52,6 +52,7 @@ object RemoveReset extends Transform with DependencyAPIMigration {
val resets = mutable.HashMap.empty[String, Reset]
val asyncResets = mutable.HashMap.empty[String, Reset]
val invalids = computeInvalids(m)
+ lazy val namespace = Namespace(m)
def onStmt(stmt: Statement): Statement = {
stmt match {
case reg @ DefRegister(_, name, _, _, reset, init) if isPreset(name) =>
@@ -93,6 +94,17 @@ object RemoveReset extends Transform with DependencyAPIMigration {
// addUpdate(info, Mux(reset, tv, fv, mux_type_and_widths(tv, fv)), Seq.empty)
val infox = MultiInfo(reset.info, reset.info, info)
Connect(infox, ref, expr)
+ /* Synchronously reset register that has reset value but only an invalid connection */
+ case IsInvalid(iinfo, ref @ WRef(rname, tpe, RegKind, _)) if resets.contains(rname) =>
+ // We need to mux with the invalid value to be consistent with async reset registers
+ val dummyWire = DefWire(iinfo, namespace.newName(rname), tpe)
+ val wireRef = Reference(dummyWire).copy(flow = SourceFlow)
+ val invalid = IsInvalid(iinfo, wireRef)
+ // Now mux between the invalid wire and the reset value
+ val Reset(cond, init, info) = resets(rname)
+ val muxType = Utils.mux_type_and_widths(init, wireRef)
+ val connect = Connect(info, ref, Mux(cond, init, wireRef, muxType))
+ Block(Seq(dummyWire, invalid, connect))
case other => other.map(onStmt)
}
}