diff options
| author | Jack Koenig | 2021-03-13 18:38:20 -0800 |
|---|---|---|
| committer | GitHub | 2021-03-14 02:38:20 +0000 |
| commit | fd55c51bcef01c2b2919817aa33c67e5a0849d05 (patch) | |
| tree | 309cfe0f72b8bf6e9cc10b4a98d32e6f6054da44 /src | |
| parent | ed1eb88d6ccdccd4b5802676cd8b69f5cc357e4f (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/passes/ZeroWidth.scala | 5 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/ZeroWidthTests.scala | 17 |
2 files changed, 20 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/passes/ZeroWidth.scala b/src/main/scala/firrtl/passes/ZeroWidth.scala index 60439ec1..e918ff63 100644 --- a/src/main/scala/firrtl/passes/ZeroWidth.scala +++ b/src/main/scala/firrtl/passes/ZeroWidth.scala @@ -135,8 +135,9 @@ object ZeroWidth extends Transform with DependencyAPIMigration { } } nonZeros match { - case Nil => UIntLiteral(ZERO, IntWidth(BigInt(1))) - case Seq(x) => x + case Nil => UIntLiteral(ZERO, IntWidth(BigInt(1))) + // 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) } case DoPrim(Andr, Seq(x), _, _) if (bitWidth(x.tpe) == 0) => UIntLiteral(1) // nothing false diff --git a/src/test/scala/firrtlTests/ZeroWidthTests.scala b/src/test/scala/firrtlTests/ZeroWidthTests.scala index 99ebbdd3..df630065 100644 --- a/src/test/scala/firrtlTests/ZeroWidthTests.scala +++ b/src/test/scala/firrtlTests/ZeroWidthTests.scala @@ -220,6 +220,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 { |
