summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala43
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Clock.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala33
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Reg.scala9
-rw-r--r--src/main/scala/chisel3/util/BitPat.scala7
-rw-r--r--src/main/scala/chisel3/util/Conditional.scala4
7 files changed, 75 insertions, 25 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index 35d2c0f6..c74b5135 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -62,6 +62,8 @@ sealed abstract class Aggregate extends Data {
}
}
+ def litToBigIntOption: Option[BigInt] = ??? // TODO implement me
+
/** Returns a Seq of the immediate contents of this Aggregate, in order.
*/
def getElements: Seq[Data]
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index 51a484f0..8368a812 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -75,6 +75,28 @@ sealed abstract class Bits(width: Width)
def cloneType: this.type = cloneTypeWidth(width)
+ protected def litArgOption: Option[LitArg] = bindingOpt match {
+ case Some(_) => topBinding match {
+ case ElementLitBinding(litArg) => Some(litArg)
+ case BundleLitBinding(litMap) => litMap.get(this) match {
+ case Some(litArg) => Some(litArg)
+ case _ => None
+ }
+ case _ => None
+ }
+ case _ => None
+ }
+
+ override def litToBigIntOption: Option[BigInt] = litArgOption match {
+ case Some(litArg) => Some(litArg.num)
+ case _ => None
+ }
+
+ private[chisel3] def litIsForcedWidth: Option[Boolean] = litArgOption match {
+ case Some(litArg) => Some(litArg.forcedWidth)
+ case _ => None
+ }
+
final def tail(n: Int): UInt = macro SourceInfoTransform.nArg
final def head(n: Int): UInt = macro SourceInfoTransform.nArg
@@ -741,6 +763,15 @@ sealed class Bool() extends UInt(1.W) with Reset {
new Bool().asInstanceOf[this.type]
}
+ def litToBooleanOption: Option[Boolean] = litToBigIntOption match {
+ case Some(intVal) if intVal == 1 => Some(true)
+ case Some(intVal) if intVal == 0 => Some(false)
+ case Some(intVal) => throwException(s"Boolean with unexpected literal value $intVal")
+ case None => None
+ }
+
+ def litToBoolean: Boolean = litToBooleanOption.get
+
// REVIEW TODO: Why does this need to exist and have different conventions
// than Bits?
final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg
@@ -820,6 +851,16 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint)
case _ => this badConnect that
}
+ def litToDoubleOption: Option[Double] = litToBigIntOption match {
+ case Some(intVal) =>
+ val multiplier = math.pow(2, binaryPoint.get)
+ Some(intVal.toDouble / multiplier)
+ case _ => None
+ }
+
+ def litToDouble: Double = litToDoubleOption.get
+
+
final def unary_- (): FixedPoint = macro SourceInfoTransform.noArg
final def unary_-% (): FixedPoint = macro SourceInfoTransform.noArg
@@ -1115,6 +1156,8 @@ final class Analog private (width: Width) extends Element(width) {
binding = target
}
+ override def litToBigIntOption = None
+
override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
throwException("Analog does not support asUInt")
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Clock.scala b/chiselFrontend/src/main/scala/chisel3/core/Clock.scala
index f682310b..55f76160 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Clock.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Clock.scala
@@ -23,6 +23,8 @@ sealed class Clock extends Element(Width(1)) {
case _ => super.badConnect(that)(sourceInfo)
}
+ override def litToBigIntOption = None
+
/** Not really supported */
def toPrintable: Printable = PString("CLOCK")
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index 36aec383..0254e14c 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -366,25 +366,33 @@ abstract class Data extends HasId with NamedComponent {
final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions)
@chiselRuntimeDeprecated
- @deprecated("Literal accessors on Data are deprecated, a replacement is pending", "chisel3.2")
+ @deprecated("litArg is deprecated, use litToBigIntOption or litTo*Option", "chisel3.2")
def litArg(): Option[LitArg] = bindingOpt match {
case Some(_) => topBinding match {
case ElementLitBinding(litArg) => Some(litArg)
- case BundleLitBinding(litMap) => litMap.get(this) match {
- case Some(litArg) => Some(litArg)
- case _ => None // DontCares in a bundle literal are treated as non-literal
- }
+ case BundleLitBinding(litMap) => None // this API does not support Bundle literals
case _ => None
}
case _ => None
}
@chiselRuntimeDeprecated
- @deprecated("Literal accessors on Data are deprecated, a replacement is pending", "chisel3.2")
+ @deprecated("litValue deprecated, use litToBigInt or litTo*", "chisel3.2")
def litValue(): BigInt = litArg.get.num
@chiselRuntimeDeprecated
- @deprecated("Literal accessors on Data are deprecated, a replacement is pending", "chisel3.2")
+ @deprecated("isLit is deprecated, use litToBigIntOption or litTo*Option", "chisel3.2")
def isLit(): Boolean = litArg.isDefined
+ /**
+ * If this is a literal that is representable as bits, returns the value as a BigInt.
+ * If not a literal, or not representable as bits (for example, is or contains Analog), returns None.
+ */
+ def litToBigIntOption: Option[BigInt]
+
+ /**
+ * Returns the literal value if this is a literal that is representable as bits, otherwise crashes.
+ */
+ def litToBigInt: BigInt = litToBigIntOption.get
+
/** Returns the width, in bits, if currently known.
* @throws java.util.NoSuchElementException if the width is not known. */
final def getWidth: Int = width.get
@@ -460,13 +468,10 @@ object Wire extends WireFactory
object WireInit {
def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val model = (init.litArg match {
+ val model = (init match {
// For e.g. Wire(init=0.U(k.W)), fix the Reg's width to k
- case Some(lit) if lit.forcedWidth => init.cloneTypeFull
- case _ => init match {
- case init: Bits => init.cloneTypeWidth(Width())
- case init => init.cloneTypeFull
- }
+ case init: Bits if init.litIsForcedWidth == Some(false) => init.cloneTypeWidth(Width())
+ case _ => init.cloneTypeFull
}).asInstanceOf[T]
apply(model, init)
}
@@ -497,6 +502,8 @@ object DontCare extends Element(width = UnknownWidth()) {
bind(DontCareBinding(), SpecifiedDirection.Output)
override def cloneType = DontCare
+ override def litToBigIntOption = None
+
def toPrintable: Printable = PString("DONTCARE")
private[core] def connectFromBits(that: chisel3.core.Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
index 14674b37..16244d12 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
@@ -69,13 +69,10 @@ object RegInit {
* Register type is inferred from the initializer.
*/
def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val model = (init.litArg match {
+ val model = (init match {
// For e.g. Reg(init=UInt(0, k)), fix the Reg's width to k
- case Some(lit) if lit.forcedWidth => init.cloneTypeFull
- case _ => init match {
- case init: Bits => init.cloneTypeWidth(Width())
- case init => init.cloneTypeFull
- }
+ case init: Bits if init.litIsForcedWidth == Some(false) => init.cloneTypeWidth(Width())
+ case init => init.cloneTypeFull
}).asInstanceOf[T]
RegInit(model, init)
}
diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala
index 8d6565fb..3a3a7061 100644
--- a/src/main/scala/chisel3/util/BitPat.scala
+++ b/src/main/scala/chisel3/util/BitPat.scala
@@ -74,9 +74,8 @@ object BitPat {
* @note the UInt must be a literal
*/
def apply(x: UInt): BitPat = {
- require(x.isLit)
val len = if (x.isWidthKnown) x.getWidth else 0
- apply("b" + x.litValue.toString(2).reverse.padTo(len, "0").reverse.mkString)
+ apply("b" + x.litToBigInt.toString(2).reverse.padTo(len, "0").reverse.mkString)
}
}
@@ -93,7 +92,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) {
def getWidth: Int = width
def === (that: UInt): Bool = macro SourceInfoTransform.thatArg
def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg
-
+
def do_=== (that: UInt) // scalastyle:ignore method.name
(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
value.asUInt === (that & mask.asUInt)
@@ -102,7 +101,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) {
(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
!(this === that)
}
-
+
def != (that: UInt): Bool = macro SourceInfoTransform.thatArg
@chiselRuntimeDeprecated
@deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala
index 860ffde3..f558b7ba 100644
--- a/src/main/scala/chisel3/util/Conditional.scala
+++ b/src/main/scala/chisel3/util/Conditional.scala
@@ -28,8 +28,8 @@ class SwitchContext[T <: Bits](cond: T, whenContext: Option[WhenContext], lits:
def is(v: Iterable[T])(block: => Unit): SwitchContext[T] = {
if (!v.isEmpty) {
val newLits = v.map { w =>
- require(w.isLit, "is conditions must be literals!")
- val value = w.litValue
+ require(w.litToBigIntOption != None, "is condition must be literal")
+ val value = w.litToBigInt
require(!lits.contains(value), "all is conditions must be mutually exclusive!")
value
}