From fcf907a8c6a3853eb63a7bba48925167fd73e965 Mon Sep 17 00:00:00 2001 From: Alan L Date: Fri, 3 Feb 2023 15:38:07 +0800 Subject: [PATCH] Fix invalid references generated by VerilogMemDelays (#2588) Transformation of mem readwriters whose address contain references to readwriters of mems declared before it would contain invalid references to untransformed memory readwriter, as the connection is not transformed. This commit fixes this issue. (cherry picked from commit 94d425f0f48e84bbae1be9d44d64615a37d960d8) --- .../passes/memlib/VerilogMemDelays.scala | 13 ++++- .../firrtlTests/VerilogMemDelaySpec.scala | 58 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala b/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala index da7497314b..2f6e105eb2 100644 --- a/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala +++ b/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala @@ -196,7 +196,18 @@ class MemDelayAndReadwriteTransformer(m: DefModule) { val transformed = m match { case mod: Module => findMemConns(mod.body) - mod.copy(body = Block(transform(mod.body) +: newConns.toSeq)) + val bodyx = transform(mod.body) + // Fixup any mem connections being driven by other transformed memories + val newConsx = newConns.map { + case sx if kind(sx.loc) == MemKind => + val (memRef, _) = Utils.splitRef(sx.loc) + if (passthroughMems(WrappedExpression(memRef))) + sx + else + sx.mapExpr(swapMemRefs) + case sx => sx + } + mod.copy(body = Block(bodyx +: newConsx.toSeq)) case mod => mod } } diff --git a/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala b/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala index 32b1c55dcb..8e6d35e0d8 100644 --- a/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala +++ b/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala @@ -198,4 +198,62 @@ class VerilogMemDelaySpec extends AnyFreeSpec with Matchers { res should include("m.write.clk <= clock") res should include("reg m_write_data_pipe_0 : UInt<8>, clock") } + + it should "VerilogMemDelays should replace expr in connections of previous mems" in { + val input = + """ + |circuit Test : + | module Test : + | input clock : Clock + | input sel : UInt<1> + | input en : UInt<1> + | output v1 : UInt<1> + | output v2 : UInt<1> + | + | mem m1 : + | data-type => UInt<1> + | depth => 2 + | read-latency => 0 + | write-latency => 1 + | readwriter => rw1 + | readwriter => rw2 + | read-under-write => undefined + | mem m2 : + | data-type => UInt<1> + | depth => 2 + | read-latency => 0 + | write-latency => 1 + | readwriter => rw1 + | readwriter => rw2 + | read-under-write => undefined + | v1 <= m1.rw2.rdata + | v2 <= m2.rw2.rdata + | m1.rw1.addr <= UInt<1>("h0") + | m2.rw1.addr <= UInt<1>("h0") + | m1.rw1.en <= UInt<1>("h1") + | m2.rw1.en <= UInt<1>("h1") + | m1.rw1.clk <= clock + | m2.rw1.clk <= clock + | m1.rw1.wmode <= en + | m2.rw1.wmode <= en + | m1.rw1.wdata <= UInt<1>("h1") + | m2.rw1.wdata <= UInt<1>("h0") + | m1.rw1.wmask <= en + | m2.rw1.wmask <= UInt<1>("h0") + | m1.rw2.addr <= m2.rw1.rdata + | m2.rw2.addr <= m2.rw1.rdata + | m1.rw2.en <= UInt<1>("h1") + | m2.rw2.en <= UInt<1>("h1") + | m1.rw2.clk <= clock + | m2.rw2.clk <= clock + | m1.rw2.wmode <= en + | m2.rw2.wmode <= en + | m1.rw2.wdata <= UInt<1>("h0") + | m2.rw2.wdata <= UInt<1>("h0") + | m1.rw2.wmask <= en + | m2.rw2.wmask <= UInt<1>("h0") + """.stripMargin + + compileTwice(input) + } }