From 527eba4966513bcfd1453fd76cfb241272fe602c Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 4 Oct 2021 22:24:51 -0400 Subject: Hotfix for Vector Reg Init LegalizeConnects Bug Add a private pass, LegalizeConnectsOnly, that behaves like LegalizeConnects, but only pads connects instead of connects and register inits. Padding is necessary for ReplSeqMem, but ReplSeqMem runs before LowerTypes and vector registers can still exist at this point. Connects, conversely, are all blown out by ExpandConnects and can be safely, blindly treated as ground type. Fixes #2379. Signed-off-by: Schuyler Eldridge --- src/main/scala/firrtl/passes/LegalizeConnects.scala | 20 ++++++++++++++++++++ .../firrtl/passes/memlib/ReplaceMemTransform.scala | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/scala/firrtl/passes/LegalizeConnects.scala b/src/main/scala/firrtl/passes/LegalizeConnects.scala index 2f29de10..9b60b5f1 100644 --- a/src/main/scala/firrtl/passes/LegalizeConnects.scala +++ b/src/main/scala/firrtl/passes/LegalizeConnects.scala @@ -29,3 +29,23 @@ object LegalizeConnects extends Pass { c.copy(modules = c.modules.map(_.mapStmt(onStmt))) } } + +/** Ensure that all connects have the same bit-width on the RHS and the LHS. + */ +private[firrtl] object LegalizeConnectsOnly extends Pass { + + override def prerequisites = Seq(Dependency(ExpandConnects)) + override def optionalPrerequisites = Seq.empty + override def optionalPrerequisiteOf = Seq.empty + override def invalidates(a: Transform) = false + + def onStmt(s: Statement): Statement = s match { + case c: Connect => + c.copy(expr = PadWidths.forceWidth(bitWidth(c.loc.tpe).toInt)(c.expr)) + case other => other.mapStmt(onStmt) + } + + def run(c: Circuit): Circuit = { + c.copy(modules = c.modules.map(_.mapStmt(onStmt))) + } +} diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala index 9acccafa..ccb6f615 100644 --- a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala +++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala @@ -152,7 +152,7 @@ class ReplSeqMem extends SeqTransform with HasShellOptions with DependencyAPIMig val transforms: Seq[Transform] = Seq( - new SimpleMidTransform(LegalizeConnects), + new SimpleMidTransform(LegalizeConnectsOnly), new SimpleMidTransform(ToMemIR), new SimpleMidTransform(ResolveMaskGranularity), new SimpleMidTransform(RenameAnnotatedMemoryPorts), -- cgit v1.2.3 From 12faf3c058675951b8d3434e2965e121900c8e6b Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 4 Oct 2021 22:49:23 -0400 Subject: Add test of #2379 issue, NFC Signed-off-by: Schuyler Eldridge --- src/test/scala/firrtlTests/ReplSeqMemTests.scala | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/scala/firrtlTests/ReplSeqMemTests.scala b/src/test/scala/firrtlTests/ReplSeqMemTests.scala index 924c767f..d9dc2e57 100644 --- a/src/test/scala/firrtlTests/ReplSeqMemTests.scala +++ b/src/test/scala/firrtlTests/ReplSeqMemTests.scala @@ -672,4 +672,25 @@ circuit Top : ) resAnnos should be(expected) } + + "ReplSeqMem" should "not crash if there are aggregate registers in the design that require padding (see #2379)" in { + + val input = + """|circuit Foo: + | module Foo: + | input clock: Clock + | input reset: UInt<1> + | input a: UInt<1>[1] + | output b: UInt<2>[1] + | + | wire init: UInt<1>[1] + | init <= a + | + | reg r : UInt<2>[1], clock with : + | reset => (reset, init) + | + | b <= r + |""".stripMargin + compileAndEmit(CircuitState(parse(input), ChirrtlForm)) + } } -- cgit v1.2.3