diff --git a/core/src/main/scala/chisel3/Num.scala b/core/src/main/scala/chisel3/Num.scala index 34c913e49ea..8e1d8aba6e4 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.{HALF_UP, RoundingMode} import chisel3.experimental.SourceInfo // REVIEW TODO: Further discussion needed on what Num actually is. @@ -199,15 +200,24 @@ 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): BigInt = { + def toBigInt(x: BigDecimal, binaryPoint: Int, roundingMode: RoundingMode): 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)