summaryrefslogtreecommitdiff
path: root/chiselFrontend
diff options
context:
space:
mode:
authorChick Markley2020-01-31 13:22:05 -0800
committerGitHub2020-01-31 13:22:05 -0800
commitefc40252631869531e79f4d8490113d18e75cc1d (patch)
treeb1377a66921f953458523b54b531298f56beeb69 /chiselFrontend
parent86e92931dd1c83a863e14b382e9f094e8b18bc5c (diff)
parentf1c4395bd608234fef5a60d8851036d1acb2382f (diff)
Merge branch 'master' into add-asbool-to-clock
Diffstat (limited to 'chiselFrontend')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Aggregate.scala6
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Bits.scala150
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Num.scala129
-rw-r--r--chiselFrontend/src/main/scala/chisel3/RawModule.scala11
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Reg.scala4
-rw-r--r--chiselFrontend/src/main/scala/chisel3/package.scala3
6 files changed, 199 insertions, 104 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/Aggregate.scala
index 8141fdba..84e959a5 100644
--- a/chiselFrontend/src/main/scala/chisel3/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Aggregate.scala
@@ -121,7 +121,7 @@ trait VecFactory extends SourceInfoDoc {
* {{{
* val io = IO(new Bundle {
* val in = Input(Vec(20, UInt(16.W)))
- * val addr = UInt(5.W)
+ * val addr = Input(UInt(5.W))
* val out = Output(UInt(16.W))
* })
* io.out := io.in(io.addr)
@@ -696,8 +696,8 @@ package experimental {
* val outPacket = Output(new Packet)
* })
* val reg = Reg(new Packet)
- * reg <> inPacket
- * outPacket <> reg
+ * reg <> io.inPacket
+ * io.outPacket <> reg
* }
* }}}
*/
diff --git a/chiselFrontend/src/main/scala/chisel3/Bits.scala b/chiselFrontend/src/main/scala/chisel3/Bits.scala
index af13ee44..57ce98d2 100644
--- a/chiselFrontend/src/main/scala/chisel3/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Bits.scala
@@ -1179,6 +1179,43 @@ package experimental {
import chisel3.internal.firrtl.BinaryPoint
+ /** Chisel types that have binary points support retrieving
+ * literal values as `Double` or `BigDecimal`
+ */
+ trait HasBinaryPoint { self: Bits =>
+ def binaryPoint: BinaryPoint
+
+ /** Return the [[Double]] value of this instance if it is a Literal
+ * @note this method may throw an exception if the literal value won't fit in a Double
+ */
+ def litToDoubleOption: Option[Double] = {
+ litOption match {
+ case Some(bigInt: BigInt) =>
+ Some(Num.toDouble(bigInt, binaryPoint))
+ case _ => None
+ }
+ }
+
+ /** Return the double value of this instance assuming it is a literal (convenience method)
+ */
+ def litToDouble: Double = litToDoubleOption.get
+
+ /** Return the [[BigDecimal]] value of this instance if it is a Literal
+ * @note this method may throw an exception if the literal value won't fit in a BigDecimal
+ */
+ def litToBigDecimalOption: Option[BigDecimal] = {
+ litOption match {
+ case Some(bigInt: BigInt) =>
+ Some(Num.toBigDecimal(bigInt, binaryPoint))
+ case _ => None
+ }
+ }
+
+ /** Return the [[BigDecimal]] value of this instance assuming it is a literal (convenience method)
+ * @return
+ */
+ def litToBigDecimal: BigDecimal = litToBigDecimalOption.get
+ }
//scalastyle:off number.of.methods
/** A sealed class representing a fixed point number that has a bit width and a binary point The width and binary point
* may be inferred.
@@ -1195,7 +1232,7 @@ package experimental {
* @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`.
*/
sealed class FixedPoint private(width: Width, val binaryPoint: BinaryPoint)
- extends Bits(width) with Num[FixedPoint] {
+ extends Bits(width) with Num[FixedPoint] with HasBinaryPoint {
override def toString: String = {
val bindingString = litToDoubleOption match {
@@ -1218,16 +1255,6 @@ package experimental {
case _ => this badConnect that
}
- /** Convert to a [[scala.Option]] of [[scala.Boolean]] */
- def litToDoubleOption: Option[Double] = litOption.map { intVal =>
- val multiplier = math.pow(2, binaryPoint.get)
- intVal.toDouble / multiplier
- }
-
- /** Convert to a [[scala.Option]] */
- def litToDouble: Double = litToDoubleOption.get
-
-
/** Unary negation (expanding width)
*
* @return a hardware $coll equal to zero minus this $coll
@@ -1519,7 +1546,7 @@ package experimental {
* Factory and convenience methods for the FixedPoint class
* IMPORTANT: The API provided here is experimental and may change in the future.
*/
- object FixedPoint {
+ object FixedPoint extends NumObject {
import FixedPoint.Implicits._
@@ -1559,6 +1586,14 @@ package experimental {
toBigInt(value, binaryPoint.get), width = width, binaryPoint = binaryPoint
)
}
+ /** Create an FixedPoint literal with inferred width from BigDecimal.
+ * Use PrivateObject to force users to specify width and binaryPoint by name
+ */
+ def fromBigDecimal(value: BigDecimal, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
+ fromBigInt(
+ toBigInt(value, binaryPoint.get), width = width, binaryPoint = binaryPoint
+ )
+ }
/** Create an FixedPoint port with specified width and binary position. */
def apply(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
@@ -1568,34 +1603,10 @@ package experimental {
lit.bindLitArg(newLiteral)
}
- /**
- * 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
- }
-
- /**
- * 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 = {
- val multiplier = math.pow(2, binaryPoint)
- val result = i.toDouble / multiplier
- result
- }
object Implicits {
- // implicit class fromDoubleToLiteral(val double: Double) extends AnyVal {
implicit class fromDoubleToLiteral(double: Double) {
def F(binaryPoint: BinaryPoint): FixedPoint = {
FixedPoint.fromDouble(double, Width(), binaryPoint)
@@ -1605,6 +1616,16 @@ package experimental {
FixedPoint.fromDouble(double, width, binaryPoint)
}
}
+
+ implicit class fromBigDecimalToLiteral(bigDecimal: BigDecimal) {
+ def F(binaryPoint: BinaryPoint): FixedPoint = {
+ FixedPoint.fromBigDecimal(bigDecimal, Width(), binaryPoint)
+ }
+
+ def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = {
+ FixedPoint.fromBigDecimal(bigDecimal, width, binaryPoint)
+ }
+ }
}
}
@@ -1627,7 +1648,7 @@ package experimental {
* @param range a range specifies min, max and binary point
*/
sealed class Interval private[chisel3] (val range: chisel3.internal.firrtl.IntervalRange)
- extends Bits(range.getWidth) with Num[Interval] {
+ extends Bits(range.getWidth) with Num[Interval] with HasBinaryPoint {
override def toString: String = {
val bindingString = litOption match {
@@ -2071,7 +2092,7 @@ package experimental {
* Factory and convenience methods for the Interval class
* IMPORTANT: The API provided here is experimental and may change in the future.
*/
- object Interval {
+ object Interval extends NumObject {
/** Create an Interval type with inferred width and binary point. */
def apply(): Interval = Interval(range"[?,?]")
@@ -2155,7 +2176,7 @@ package experimental {
case _ =>
}
val lit = IntervalLit(value, width, binaryPoint)
- val bound = firrtlir.Closed(Interval.toDouble(value, binaryPoint.asInstanceOf[KnownBinaryPoint].value))
+ val bound = firrtlir.Closed(Interval.toBigDecimal(value, binaryPoint.asInstanceOf[KnownBinaryPoint].value))
val result = new Interval(IntervalRange(bound, bound, binaryPoint))
lit.bindLitArg(result)
}
@@ -2178,55 +2199,8 @@ package experimental {
lit.bindLitArg(result)
}
- /** 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: BinaryPoint): BigInt = {
- val intBinaryPoint = binaryPoint match {
- case KnownBinaryPoint(n) => n
- case b =>
- throw new ChiselException(s"Error converting Double $x to BigInt, binary point must be known, not $b")
- }
- val multiplier = BigInt(1) << intBinaryPoint
- val result = BigInt(math.round(x * multiplier.doubleValue))
- result
-
- }
-
- /**
- * How to create a BigInt from a BigDecimal with a specific binaryPoint
- *
- * @param b a BigDecimal value
- * @param binaryPoint a binaryPoint that you would like to use
- * @return
- */
- def toBigInt(b: BigDecimal, binaryPoint: BinaryPoint): BigInt = {
- val bp = binaryPoint match {
- case KnownBinaryPoint(n) => n
- case x =>
- throw new ChiselException(s"Error converting BigDecimal $b to BigInt, binary point must be known, not $x")
- }
- (b * math.pow(2.0, bp.toDouble)).toBigInt
- }
-
- /**
- * 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 = {
- val multiplier = BigInt(1) << binaryPoint
- val result = i.toDouble / multiplier.doubleValue
- result
- }
-
/**
- * This returns the smallest number that can legally fit in range, if possible
+ * This returns the smallest Interval literal that can legally fit in range, if possible
* If the lower bound or binary point is not known then return None
*
* @param range use to figure low number
@@ -2245,7 +2219,7 @@ package experimental {
}
/**
- * This returns the largest number that can legally fit in range, if possible
+ * This returns the largest Interval literal that can legally fit in range, if possible
* If the upper bound or binary point is not known then return None
*
* @param range use to figure low number
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
diff --git a/chiselFrontend/src/main/scala/chisel3/RawModule.scala b/chiselFrontend/src/main/scala/chisel3/RawModule.scala
index 4155ef4a..2b184a50 100644
--- a/chiselFrontend/src/main/scala/chisel3/RawModule.scala
+++ b/chiselFrontend/src/main/scala/chisel3/RawModule.scala
@@ -184,17 +184,6 @@ package internal {
// Allow access to bindings from the compatibility package
protected def _compatIoPortBound() = portsContains(io)// scalastyle:ignore method.name
- protected override def nameIds(rootClass: Class[_]): HashMap[HasId, String] = {
- val names = super.nameIds(rootClass)
-
- // Allow IO naming without reflection
- names.put(io, "io")
- names.put(clock, "clock")
- names.put(reset, "reset")
-
- names
- }
-
private[chisel3] override def namePorts(names: HashMap[HasId, String]): Unit = {
for (port <- getModulePorts) {
// This should already have been caught
diff --git a/chiselFrontend/src/main/scala/chisel3/Reg.scala b/chiselFrontend/src/main/scala/chisel3/Reg.scala
index 51c59bdb..a3e6b2a0 100644
--- a/chiselFrontend/src/main/scala/chisel3/Reg.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Reg.scala
@@ -108,13 +108,13 @@ object RegNext {
* val x = Wire(UInt())
* val y = Wire(UInt(8.W))
* val r1 = RegInit(x) // width will be inferred
- * val r2 = RegInit(y) // width will be inferred
+ * val r2 = RegInit(y) // width is set to 8
* }}}
*
* 3. [[Aggregate]] initializer - width will be set to match the aggregate
*
* {{{
- * class MyBundle {
+ * class MyBundle extends Bundle {
* val unknown = UInt()
* val known = UInt(8.W)
* }
diff --git a/chiselFrontend/src/main/scala/chisel3/package.scala b/chiselFrontend/src/main/scala/chisel3/package.scala
index 3af21d57..65bfdeb7 100644
--- a/chiselFrontend/src/main/scala/chisel3/package.scala
+++ b/chiselFrontend/src/main/scala/chisel3/package.scala
@@ -115,6 +115,9 @@ package object chisel3 { // scalastyle:ignore package.object.name
implicit class fromDoubleToLiteral(double: Double)
extends experimental.FixedPoint.Implicits.fromDoubleToLiteral(double)
+ implicit class fromBigDecimalToLiteral(bigDecimal: BigDecimal)
+ extends experimental.FixedPoint.Implicits.fromBigDecimalToLiteral(bigDecimal)
+
// Interval is experimental for now, but we alias the implicit conversion classes here
// to minimize disruption with existing code.
implicit class fromIntToLiteralInterval(int: Int)