From dac52bde1b75a3c72c5803fee41db760b4bccae8 Mon Sep 17 00:00:00 2001 From: Michiel Van Beirendonck Date: Fri, 8 Mar 2024 09:48:02 +0100 Subject: [PATCH 1/3] toBigInt should round identically for Double and BigDecimal --- core/src/main/scala/chisel3/Num.scala | 5 +++-- .../scala/chiselTests/LiteralExtractorSpec.scala | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/chisel3/Num.scala b/core/src/main/scala/chisel3/Num.scala index 34c913e49ea..d0afa794451 100644 --- a/core/src/main/scala/chisel3/Num.scala +++ b/core/src/main/scala/chisel3/Num.scala @@ -5,6 +5,7 @@ package chisel3 import chisel3.internal.sourceinfo.SourceInfoTransform import scala.language.experimental.macros +import scala.math.BigDecimal.RoundingMode._ import chisel3.experimental.SourceInfo // REVIEW TODO: Further discussion needed on what Num actually is. @@ -205,9 +206,9 @@ trait NumObject { * @param binaryPoint a binaryPoint that you would like to use * @return */ - def toBigInt(x: BigDecimal, binaryPoint: Int): BigInt = { + def toBigInt(x: BigDecimal, binaryPoint: Int, roundingMode: RoundingMode = HALF_UP): BigInt = { val multiplier = math.pow(2, binaryPoint) - val result = (x * multiplier).rounded.toBigInt + val result = (x * multiplier).setScale(0, roundingMode).toBigInt result } diff --git a/src/test/scala/chiselTests/LiteralExtractorSpec.scala b/src/test/scala/chiselTests/LiteralExtractorSpec.scala index 270a5131f03..281215ab0da 100644 --- a/src/test/scala/chiselTests/LiteralExtractorSpec.scala +++ b/src/test/scala/chiselTests/LiteralExtractorSpec.scala @@ -59,6 +59,20 @@ class LiteralExtractorSpec extends ChiselFlatSpec { bigIntFromDouble should be(bigInt53) } + "doubles and big decimals" should "be rounded identically" in { + + for (double <- Seq(1.0, 1.1, 1.5, 1.6, 2.5)) { + + val bigDecimal = BigDecimal(double) + + val bigIntFromDouble = Num.toBigInt(double, 0) + val bigIntFromBigDecimal = Num.toBigInt(bigDecimal, 0) + + bigIntFromDouble should be(bigIntFromBigDecimal) + } + + } + "literals declared outside a builder context" should "compare with those inside builder context" in { class InsideBundle extends Bundle { val x = SInt(8.W) From cf10496836e9c0a2f6835ae0840c293d582d3c5d Mon Sep 17 00:00:00 2001 From: Michiel Van Beirendonck Date: Mon, 11 Mar 2024 08:27:08 +0100 Subject: [PATCH 2/3] Avoid wildcard RoundingMode import Co-authored-by: Schuyler Eldridge --- core/src/main/scala/chisel3/Num.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/Num.scala b/core/src/main/scala/chisel3/Num.scala index d0afa794451..f67c105143a 100644 --- a/core/src/main/scala/chisel3/Num.scala +++ b/core/src/main/scala/chisel3/Num.scala @@ -5,7 +5,7 @@ package chisel3 import chisel3.internal.sourceinfo.SourceInfoTransform import scala.language.experimental.macros -import scala.math.BigDecimal.RoundingMode._ +import scala.math.BigDecimal.RoundingMode.{HALF_UP, RoundingMode} import chisel3.experimental.SourceInfo // REVIEW TODO: Further discussion needed on what Num actually is. From 62c81fbef7df7afcaf252680b95d601d2d921234 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Tue, 12 Mar 2024 08:42:47 -0700 Subject: [PATCH 3/3] Use overloading instead of default arguments --- core/src/main/scala/chisel3/Num.scala | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/chisel3/Num.scala b/core/src/main/scala/chisel3/Num.scala index f67c105143a..8e1d8aba6e4 100644 --- a/core/src/main/scala/chisel3/Num.scala +++ b/core/src/main/scala/chisel3/Num.scala @@ -200,13 +200,22 @@ trait NumObject { result } - /** - * How to create a bigint from a big decimal with a specific binaryPoint (int) - * @param x a BigDecimal value - * @param binaryPoint a binaryPoint that you would like to use + /** Create a bigint from a big decimal with a specific binaryPoint (Int) + * + * @param x the BigDecimal value + * @param binaryPoint the binaryPoint to use + * @return + */ + def toBigInt(x: BigDecimal, binaryPoint: Int): BigInt = toBigInt(x, binaryPoint, HALF_UP) + + /** Create a bigint from a big decimal with a specific binaryPoint (Int) + * + * @param x the BigDecimal value + * @param binaryPoint the binaryPoint to use + * @param roundingMode the RoundingMode to use * @return */ - def toBigInt(x: BigDecimal, binaryPoint: Int, roundingMode: RoundingMode = HALF_UP): BigInt = { + def toBigInt(x: BigDecimal, binaryPoint: Int, roundingMode: RoundingMode): BigInt = { val multiplier = math.pow(2, binaryPoint) val result = (x * multiplier).setScale(0, roundingMode).toBigInt result