aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala
diff options
context:
space:
mode:
authorAdam Izraelevitz2020-02-11 18:56:57 -0800
committerGitHub2020-02-12 02:56:57 +0000
commitce056037bb08d9604b503d5052fb3fc45a21e5a9 (patch)
tree211645a902d50452b6835867e77a02a1e6217342 /src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala
parentdb9a16dbe382359043d996f7de570880ad02eb98 (diff)
Fixing lint error: x + -1 (#1374)
* Generates lint-clean Verilog for the case: x + -1 ...where x is anything and 1 is any literal. Master behavior: input x : SInt<8> output z : SInt<9> z <= add(x, SInt(-2)) generates assign z = $signed(x) + -8'sh2; After this PR: assign z = $signed(x) - 8'sh2; If the literal is the maximum possible literal, a special case is triggered to properly trim the resulting subtraction. Input: input x : SInt<2> output z : SInt<3> z <= add(x, SInt(-2)) now generates (after this PR) assign z = $signed(x) - 3'sh2; * Updated documentation * Change ArrayBuffer to ListBuffer * Change name to minNegValue * Remove mutable public interfaces Co-authored-by: Albert Magyar <albert.magyar@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Diffstat (limited to 'src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala')
-rw-r--r--src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala b/src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala
index 1fe9a723..8aa1553a 100644
--- a/src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala
+++ b/src/main/scala/firrtl/transforms/ReplaceTruncatingArithmetic.scala
@@ -1,3 +1,5 @@
+// See LICENSE for license details.
+
package firrtl
package transforms
@@ -24,10 +26,22 @@ object ReplaceTruncatingArithmetic {
*/
def onExpr(netlist: Netlist)(expr: Expression): Expression =
expr.map(onExpr(netlist)) match {
+ // If an unsigned wrapping add/sub
case orig @ DoPrim(Tail, Seq(e), SeqBIOne, tailtpe) =>
netlist.getOrElse(we(e), e) match {
- case DoPrim(Add, args, cs, _) => DoPrim(Addw, args, cs, tailtpe)
- case DoPrim(Sub, args, cs, _) => DoPrim(Subw, args, cs, tailtpe)
+ case DoPrim(Add, args, cs, u: UIntType) => DoPrim(Addw, args, cs, tailtpe)
+ case DoPrim(Sub, args, cs, u: UIntType) => DoPrim(Subw, args, cs, tailtpe)
+ case _ => orig // Not a candidate
+ }
+ // If a signed wrapping add/sub, there should be a cast
+ case orig @ DoPrim(AsSInt, Seq(x), _, casttpe) =>
+ netlist.getOrElse(we(x), x) match {
+ case DoPrim(Tail, Seq(e), SeqBIOne, tailtpe) =>
+ netlist.getOrElse(we(e), e) match {
+ case DoPrim(Add, args, cs, s: SIntType) => DoPrim(Addw, args, cs, casttpe)
+ case DoPrim(Sub, args, cs, s: SIntType) => DoPrim(Subw, args, cs, casttpe)
+ case _ => orig // Not a candidate
+ }
case _ => orig // Not a candidate
}
case other => other // Not a candidate