aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorFabian Schuiki2021-04-16 16:18:32 +0200
committerGitHub2021-04-16 14:18:32 +0000
commite9b2946c962f91a04611e32b1a9d03f78e7edf2b (patch)
tree20f2ff423691446e3fcfcab5ce630ab2923b3c8c /src/test
parentfc86112bc09f3e804d76e329fea96acb70e4909d (diff)
Fix signedness of xor const prop with zero (#2179)
Constant propagation of the Xor op folds `xor(a, SInt(0))` to `asUInt(a)`. For comparison, Or folds to `asUInt(pad(a, W))`. This can be a problem in the following case: circuit Foo : module Foo : input a: UInt<3> output b: UInt<4> b <= asUInt(xor(asSInt(a), SInt<4>(0))) This would emit the assignment as `b = a` instead of the sign-extended `b = {{1{a[2]}},a}`. This requires adjusting the `pad(e, t)` function use in const prop, which currently just inserts a `Pad` prim op with the requested output type. However, the function advertises that it pads *to the width* of the type `t`. Some of the folds rely on this and request the padding of a SInt<N> to the width of a UInt<M>. But the current implementation then then actually returns a `Pad` op with type UInt<M>, instead of the SInt<M> that was requested.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/ConstantPropagationTests.scala7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/ConstantPropagationTests.scala b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
index bc7f92e6..ababb95b 100644
--- a/src/test/scala/firrtlTests/ConstantPropagationTests.scala
+++ b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
@@ -1531,22 +1531,29 @@ class ConstantPropagationIntegrationSpec extends LowTransformSpec {
val input =
s"""|circuit Foo:
| module Foo:
+ | input in1: SInt<3>
| output out1: UInt<2>
| output out2: UInt<2>
| output out3: UInt<2>
+ | output out4: UInt<4>
| out1 <= xor(SInt<2>(-1), SInt<2>(1))
| out2 <= or(SInt<2>(-1), SInt<2>(1))
| out3 <= and(SInt<2>(-1), SInt<2>(-2))
+ | out4 <= xor(in1, SInt<4>(0))
|""".stripMargin
val check =
s"""|circuit Foo:
| module Foo:
+ | input in1: SInt<3>
| output out1: UInt<2>
| output out2: UInt<2>
| output out3: UInt<2>
+ | output out4: UInt<4>
| out1 <= UInt<2>(2)
| out2 <= UInt<2>(3)
| out3 <= UInt<2>(2)
+ | node _GEN_0 = pad(in1, 4)
+ | out4 <= asUInt(_GEN_0)
|""".stripMargin
execute(input, check, Seq.empty)
}