summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/Num.scala
diff options
context:
space:
mode:
authorChick Markley2020-01-23 12:06:53 -0800
committerGitHub2020-01-23 12:06:53 -0800
commit37e2b8fee3c9d583fa9d023637e8bc327dc9866f (patch)
tree56de0ff88ae71326064ef9ec033594b89a84ff70 /chiselFrontend/src/main/scala/chisel3/Num.scala
parent993ee4ed8b95e2c78f6fc54ecbd828ac06a32b8b (diff)
parent481736c3ebce29932b54ac72e01d6656e4995fca (diff)
Merge pull request #1284 from freechipsproject/big-decimal-methods-for-num-types
Provides Double and BigDecimal methods to access literal values for FixedPoint and Interval
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/Num.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Num.scala129
1 files changed, 129 insertions, 0 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Num.scala b/chiselFrontend/src/main/scala/chisel3/Num.scala
index 8984697f..7a6b0744 100644
--- a/chiselFrontend/src/main/scala/chisel3/Num.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Num.scala
@@ -2,6 +2,9 @@
package chisel3
+import chisel3.internal.ChiselException
+import chisel3.internal.firrtl.{BinaryPoint, KnownBinaryPoint}
+
import scala.language.experimental.macros
import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform}
@@ -177,3 +180,129 @@ trait Num[T <: Data] {
def do_max(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
Mux(this < that, that, this.asInstanceOf[T])
}
+
+object Num extends NumObject
+
+/** NumbObject has a lot of convenience methods for converting between
+ * BigInts and Double and BigDecimal
+ * For backwards compatibility this is used with FixedPoint and Interval objects
+ * but is better used with the Num Object
+ *
+ */
+trait NumObject {
+ val MaxBitsBigIntToBigDecimal = 108
+ val MaxBitsBigIntToDouble = 53
+
+ /**
+ * How to create a bigint from a double with a specific binaryPoint
+ * @param x a double value
+ * @param binaryPoint a binaryPoint that you would like to use
+ * @return
+ */
+ def toBigInt(x: Double, binaryPoint: Int): BigInt = {
+ val multiplier = math.pow(2, binaryPoint)
+ val result = BigInt(math.round(x * multiplier))
+ result
+ }
+
+ /**
+ * How to create a bigint from a big decimal with a specific binaryPoint
+ * @param x a BigDecimal value
+ * @param binaryPoint a binaryPoint that you would like to use
+ * @return
+ */
+ def toBigInt(x: Double, binaryPoint: BinaryPoint): BigInt = {
+ binaryPoint match {
+ case KnownBinaryPoint(n) => toBigInt(x, n)
+ case x =>
+ throw new ChiselException(s"Error converting Double $x to BigInt, binary point must be known, not $x")
+ }
+ }
+
+ /**
+ * 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
+ * @return
+ */
+ def toBigInt(x: BigDecimal, binaryPoint: Int): BigInt = {
+ val multiplier = math.pow(2, binaryPoint)
+ val result = (x * multiplier).rounded.toBigInt()
+ result
+ }
+
+ /**
+ * How to create a bigint from a big decimal with a specific binaryPoint
+ * @param value a BigDecimal value
+ * @param binaryPoint a binaryPoint that you would like to use
+ * @return
+ */
+ def toBigInt(value: BigDecimal, binaryPoint: BinaryPoint): BigInt = {
+ binaryPoint match {
+ case KnownBinaryPoint(n) => toBigInt(value, n)
+ case x =>
+ throw new ChiselException(s"Error converting BigDecimal $value to BigInt, binary point must be known, not $x")
+ }
+ }
+
+ /**
+ * converts a bigInt with the given binaryPoint into the double representation
+ * @param i a bigint
+ * @param binaryPoint the implied binaryPoint of @i
+ * @return
+ */
+ def toDouble(i: BigInt, binaryPoint: Int): Double = {
+ if(i.bitLength >= 54) {
+ throw new ChiselException(
+ s"BigInt $i with bitlength ${i.bitLength} is too big, precision lost with > $MaxBitsBigIntToDouble bits"
+ )
+ }
+ val multiplier = math.pow(2, binaryPoint)
+ val result = i.toDouble / multiplier
+ result
+ }
+
+ /**
+ * converts a bigInt with the given binaryPoint into the double representation
+ * @param value a bigint
+ * @param binaryPoint the implied binaryPoint of @i
+ * @return
+ */
+ def toDouble(value: BigInt, binaryPoint: BinaryPoint): Double = {
+ binaryPoint match {
+ case KnownBinaryPoint(n) => toDouble(value, n)
+ case x =>
+ throw new ChiselException(s"Error converting BigDecimal $value to BigInt, binary point must be known, not $x")
+ } }
+
+ /**
+ * converts a bigInt with the given binaryPoint into the BigDecimal representation
+ * @param value a bigint
+ * @param binaryPoint the implied binaryPoint of @i
+ * @return
+ */
+ def toBigDecimal(value: BigInt, binaryPoint: Int): BigDecimal = {
+ if(value.bitLength > MaxBitsBigIntToBigDecimal) {
+ throw new ChiselException(
+ s"BigInt $value with bitlength ${value.bitLength} is too big, precision lost with > $MaxBitsBigIntToBigDecimal bits"
+ )
+ }
+ val multiplier = BigDecimal(1.0) / BigDecimal(math.pow(2, binaryPoint))
+ val result = BigDecimal(value) * multiplier
+ result
+ }
+
+ /**
+ * converts a bigInt with the given binaryPoint into the BigDecimal representation
+ * @param value a bigint
+ * @param binaryPoint the implied binaryPoint of @i
+ * @return
+ */
+ def toBigDecimal(value: BigInt, binaryPoint: BinaryPoint): BigDecimal = {
+ binaryPoint match {
+ case KnownBinaryPoint(n) => toBigDecimal(value, n)
+ case x =>
+ throw new ChiselException(s"Error converting BigDecimal $value to BigInt, binary point must be known, not $x")
+ }
+ }
+} \ No newline at end of file