From 51b02dd3a0ca79c5ad99a1556d62064b6e1bca8a Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Sat, 13 Mar 2021 18:38:20 -0800 Subject: [PATCH] Fix cat of zero-width SInt (#2116) Previously, concatenating two SInts where one is of zero-width would return the non-zero-width SInt. This is incorrect because the output of Cat should be of type UInt. Now the ZeroWidth transform will introduce a cast when removing a Cat when the argument type is non-UInt. (cherry picked from commit fd55c51bcef01c2b2919817aa33c67e5a0849d05) # Conflicts: # src/main/scala/firrtl/passes/ZeroWidth.scala --- src/main/scala/firrtl/passes/ZeroWidth.scala | 6 ++++++ src/test/scala/firrtlTests/ZeroWidthTests.scala | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/main/scala/firrtl/passes/ZeroWidth.scala b/src/main/scala/firrtl/passes/ZeroWidth.scala index 4f7e236918..e350e593a2 100644 --- a/src/main/scala/firrtl/passes/ZeroWidth.scala +++ b/src/main/scala/firrtl/passes/ZeroWidth.scala @@ -124,8 +124,14 @@ object ZeroWidth extends Transform with DependencyAPIMigration { } nonZeros match { case Nil => UIntLiteral(ZERO, IntWidth(BigInt(1))) +<<<<<<< HEAD case Seq(x) => x case seq => DoPrim(Cat, seq, consts, tpe) map onExp +======= + // We may have an SInt, Cat has type UInt so cast + case Seq(x) => castRhs(tpe, x) + case seq => DoPrim(Cat, seq, consts, tpe).map(onExp) +>>>>>>> fd55c51b... Fix cat of zero-width SInt (#2116) } case DoPrim(Andr, Seq(x), _, _) if (bitWidth(x.tpe) == 0) => UIntLiteral(1) // nothing false case other => other.tpe match { diff --git a/src/test/scala/firrtlTests/ZeroWidthTests.scala b/src/test/scala/firrtlTests/ZeroWidthTests.scala index b53f55ea71..ab2631a4a9 100644 --- a/src/test/scala/firrtlTests/ZeroWidthTests.scala +++ b/src/test/scala/firrtlTests/ZeroWidthTests.scala @@ -223,6 +223,23 @@ class ZeroWidthTests extends FirrtlFlatSpec { | x <= UInt<1>(1)""".stripMargin (parse(exec(input))) should be (parse(check)) } + + "Cat of SInt with zero-width" should "keep type correctly" in { + val input = + """circuit Top : + | module Top : + | input x : SInt<0> + | input y : SInt<1> + | output z : UInt<1> + | z <= cat(y, x)""".stripMargin + val check = + """circuit Top : + | module Top : + | input y : SInt<1> + | output z : UInt<1> + | z <= asUInt(y)""".stripMargin + (parse(exec(input))) should be(parse(check)) + } } class ZeroWidthVerilog extends FirrtlFlatSpec {