From 0861510ebe111ebce39224f36f714f37f6ee9b8d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 26 Mar 2021 18:10:48 +0000 Subject: [PATCH] Fix bug in zero-width memory removal (bp #2153) (#2155) * Fix bug in zero-width memory removal (#2153) * Fix bug in zero-width memory removal Correctly remove all extraneous connections to all types of memory ports (read, write, readwrite) for zero-width memories. Previously, only read ports were correctly handled. Signed-off-by: Schuyler Eldridge * fixup! Fix bug in zero-width memory removal (cherry picked from commit 67ce97a10564cfa07829af8cfce562009d60bafb) # Conflicts: # src/main/scala/firrtl/passes/ZeroWidth.scala * fixup! Fix bug in zero-width memory removal (#2153) Co-authored-by: Schuyler Eldridge --- src/main/scala/firrtl/passes/ZeroWidth.scala | 36 ++++++----- .../scala/firrtlTests/ZeroWidthTests.scala | 63 +++++++++++++++++++ 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/main/scala/firrtl/passes/ZeroWidth.scala b/src/main/scala/firrtl/passes/ZeroWidth.scala index 6a61555025..c28b991abb 100644 --- a/src/main/scala/firrtl/passes/ZeroWidth.scala +++ b/src/main/scala/firrtl/passes/ZeroWidth.scala @@ -24,25 +24,27 @@ object ZeroWidth extends Transform with DependencyAPIMigration { case _ => false } - private def makeEmptyMemBundle(name: String): Field = - Field(name, Flip, BundleType(Seq( - Field("addr", Default, UIntType(IntWidth(0))), - Field("en", Default, UIntType(IntWidth(0))), - Field("clk", Default, UIntType(IntWidth(0))), - Field("data", Flip, UIntType(IntWidth(0))) - ))) + private def makeZero(tpe: ir.Type): ir.Type = tpe match { + case ClockType => UIntType(IntWidth(0)) + case a: UIntType => a.copy(IntWidth(0)) + case a: SIntType => a.copy(IntWidth(0)) + case a: AggregateType => a.map(makeZero) + } private def onEmptyMemStmt(s: Statement): Statement = s match { - case d @ DefMemory(info, name, tpe, _, _, _, rs, ws, rws, _) => removeZero(tpe) match { - case None => - DefWire(info, name, BundleType( - rs.map(r => makeEmptyMemBundle(r)) ++ - ws.map(w => makeEmptyMemBundle(w)) ++ - rws.map(rw => makeEmptyMemBundle(rw)) - )) - case Some(_) => d - } - case sx => sx map onEmptyMemStmt + case d @ DefMemory(info, name, tpe, _, _, _, rs, ws, rws, _) => + removeZero(tpe) match { + case None => + DefWire( + info, + name, + MemPortUtils + .memType(d) + .map(makeZero) + ) + case Some(_) => d + } + case sx => sx.map(onEmptyMemStmt) } private def onModuleEmptyMemStmt(m: DefModule): DefModule = { diff --git a/src/test/scala/firrtlTests/ZeroWidthTests.scala b/src/test/scala/firrtlTests/ZeroWidthTests.scala index ab2631a4a9..d4d4978d03 100644 --- a/src/test/scala/firrtlTests/ZeroWidthTests.scala +++ b/src/test/scala/firrtlTests/ZeroWidthTests.scala @@ -240,6 +240,69 @@ class ZeroWidthTests extends FirrtlFlatSpec { | z <= asUInt(y)""".stripMargin (parse(exec(input))) should be(parse(check)) } + + "Memories with zero-width data-type" should "be fully removed" in { + val input = + """circuit Foo: + | module Foo: + | input clock: Clock + | input rAddr: UInt<4> + | input rEn: UInt<1> + | output rData: UInt<0> + | input wAddr: UInt<4> + | input wEn: UInt<1> + | input wMask: UInt<1> + | input wData: UInt<0> + | input rwEn: UInt<1> + | input rwMode: UInt<1> + | input rwAddr: UInt<1> + | input rwMask: UInt<1> + | input rwDataIn: UInt<0> + | output rwDataOut: UInt<0> + | + | mem memory: + | data-type => UInt<0> + | depth => 16 + | reader => r + | writer => w + | readwriter => rw + | read-latency => 0 + | write-latency => 1 + | read-under-write => undefined + | + | memory.r.clk <= clock + | memory.r.en <= rEn + | memory.r.addr <= rAddr + | rData <= memory.r.data + | memory.w.clk <= clock + | memory.w.en <= wEn + | memory.w.addr <= wAddr + | memory.w.mask <= wMask + | memory.w.data <= wData + | memory.rw.clk <= clock + | memory.rw.en <= rwEn + | memory.rw.addr <= rwAddr + | memory.rw.wmode <= rwMode + | memory.rw.wmask <= rwMask + | memory.rw.wdata <= rwDataIn + | rwDataOut <= memory.rw.rdata""".stripMargin + val check = + s"""circuit Foo: + | module Foo: + | input clock: Clock + | input rAddr: UInt<4> + | input rEn: UInt<1> + | input wAddr: UInt<4> + | input wEn: UInt<1> + | input wMask: UInt<1> + | input rwEn: UInt<1> + | input rwMode: UInt<1> + | input rwAddr: UInt<1> + | input rwMask: UInt<1> + | + |${Seq.tabulate(17)(_ => " skip").mkString("\n")}""".stripMargin + parse(exec(input)) should be(parse(check)) + } } class ZeroWidthVerilog extends FirrtlFlatSpec {