summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorducky2018-05-02 11:45:22 -0700
committerRichard Lin2018-07-04 18:39:28 -0500
commitb74034446223db6731c7e4f2eb362b3349efc8be (patch)
tree317b55c2c2a11217dc452addb427e57bdac3a2c5
parent3d8064a9f2fd49bffb402b91131087c19ca7d6fc (diff)
Infrastructure for bundle literals
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Binding.scala9
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala52
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala19
3 files changed, 45 insertions, 35 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
index d60fb723..ecec3676 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
@@ -1,6 +1,7 @@
package chisel3.core
import chisel3.internal.Builder.{forcedModule}
+import chisel3.internal.firrtl.LitArg
object Binding {
class BindingException(message: String) extends Exception(message)
@@ -92,8 +93,6 @@ sealed trait ConstrainedBinding extends TopBinding {
// A binding representing a data that cannot be (re)assigned to.
sealed trait ReadOnlyBinding extends TopBinding
-// TODO literal info here
-case class LitBinding() extends UnconstrainedBinding with ReadOnlyBinding
// TODO(twigg): Ops between unenclosed nodes can also be unenclosed
// However, Chisel currently binds all op results to a module
case class OpBinding(enclosure: UserModule) extends ConstrainedBinding with ReadOnlyBinding
@@ -108,3 +107,9 @@ case class ChildBinding(parent: Data) extends Binding {
// A DontCare element has a specific Binding, somewhat like a literal.
// It is a source (RHS). It may only be connected/applied to sinks.
case class DontCareBinding() extends UnconstrainedBinding
+
+sealed trait LitBinding extends UnconstrainedBinding with ReadOnlyBinding
+// Literal binding attached to a element that is not part of a Bundle.
+case class ElementLitBinding(litArg: LitArg) extends LitBinding
+// Literal binding attached to the root of a Bundle, containing literal values of its children.
+case class BundleLitBinding(litMap: Map[Data, LitArg]) extends LitBinding
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index dd99d822..51a484f0 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -61,7 +61,7 @@ private[chisel3] sealed trait ToBoolable extends Element {
* bitwise operations.
*/
//scalastyle:off number.of.methods
-sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
+sealed abstract class Bits(width: Width)
extends Element(width) with ToBoolable {
// TODO: perhaps make this concrete?
// Arguments for: self-checking code (can't do arithmetic on bits)
@@ -106,13 +106,8 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
if (x < 0) {
Builder.error(s"Negative bit indices are illegal (got $x)")
}
- if (isLit()) {
- (((litValue() >> x.toInt) & 1) == 1).asBool
- } else {
-
- requireIsHardware(this, "bits to be indexed")
- pushOp(DefPrim(sourceInfo, Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x)))
- }
+ requireIsHardware(this, "bits to be indexed")
+ pushOp(DefPrim(sourceInfo, Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x)))
}
/** Returns the specified bit on this wire as a [[Bool]], statically
@@ -150,12 +145,8 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
Builder.error(s"Invalid bit range ($x,$y)")
}
val w = x - y + 1
- if (isLit()) {
- ((litValue >> y) & ((BigInt(1) << w) - 1)).asUInt(w.W)
- } else {
- requireIsHardware(this, "bits to be sliced")
- pushOp(DefPrim(sourceInfo, UInt(Width(w)), BitsExtractOp, this.ref, ILit(x), ILit(y)))
- }
+ requireIsHardware(this, "bits to be sliced")
+ pushOp(DefPrim(sourceInfo, UInt(Width(w)), BitsExtractOp, this.ref, ILit(x), ILit(y)))
}
// REVIEW TODO: again, is this necessary? Or just have this and use implicits?
@@ -295,7 +286,7 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
implicit val sourceInfo = DeprecatedSourceInfo
do_asSInt
}
-
+
@chiselRuntimeDeprecated
@deprecated("Use asUInt, which makes the reinterpret cast more explicit", "chisel3")
final def toUInt(implicit compileOptions: CompileOptions): UInt = {
@@ -428,8 +419,8 @@ abstract trait Num[T <: Data] {
/** A data type for unsigned integers, represented as a binary bitvector.
* Defines arithmetic operations between other integer types.
*/
-sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
- extends Bits(width, lit) with Num[UInt] {
+sealed class UInt private[core] (width: Width)
+ extends Bits(width) with Num[UInt] {
private[core] override def typeEquivalent(that: Data): Boolean =
that.isInstanceOf[UInt] && this.width == that.width
@@ -576,9 +567,9 @@ trait UIntFactory {
/** Create a UInt literal with specified width. */
protected[chisel3] def Lit(value: BigInt, width: Width): UInt = {
val lit = ULit(value, width)
- val result = new UInt(lit.width, Some(lit))
+ val result = new UInt(lit.width)
// Bind result to being an Literal
- result.bind(LitBinding())
+ result.bind(ElementLitBinding(lit))
result
}
@@ -595,8 +586,7 @@ trait UIntFactory {
object UInt extends UIntFactory
object Bits extends UIntFactory
-sealed class SInt private[core] (width: Width, lit: Option[SLit] = None)
- extends Bits(width, lit) with Num[SInt] {
+sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt] {
private[core] override def typeEquivalent(that: Data): Boolean =
this.getClass == that.getClass && this.width == that.width // TODO: should this be true for unspecified widths?
@@ -731,9 +721,8 @@ trait SIntFactory {
/** Create an SInt literal with specified width. */
protected[chisel3] def Lit(value: BigInt, width: Width): SInt = {
val lit = SLit(value, width)
- val result = new SInt(lit.width, Some(lit))
- // Bind result to being an Literal
- result.bind(LitBinding())
+ val result = new SInt(lit.width)
+ result.bind(ElementLitBinding(lit))
result
}
}
@@ -746,7 +735,7 @@ sealed trait Reset extends Element with ToBoolable
// operations on a Bool make sense?
/** A data type for booleans, defined as a single bit indicating true or false.
*/
-sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) with Reset {
+sealed class Bool() extends UInt(1.W) with Reset {
private[core] override def cloneTypeWidth(w: Width): this.type = {
require(!w.known || w.get == 1)
new Bool().asInstanceOf[this.type]
@@ -795,9 +784,8 @@ trait BoolFactory {
/** Creates Bool literal.
*/
protected[chisel3] def Lit(x: Boolean): Bool = {
- val result = new Bool(Some(ULit(if (x) 1 else 0, Width(1))))
- // Bind result to being an Literal
- result.bind(LitBinding())
+ val result = new Bool()
+ result.bind(ElementLitBinding(ULit(if (x) 1 else 0, Width(1))))
result
}
}
@@ -817,8 +805,8 @@ object Bool extends BoolFactory
* and thus use this field as a simple exponent
* @param lit
*/
-sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit: Option[FPLit] = None)
- extends Bits(width, lit) with Num[FixedPoint] {
+sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint)
+ extends Bits(width) with Num[FixedPoint] {
private[core] override def typeEquivalent(that: Data): Boolean = that match {
case that: FixedPoint => this.width == that.width && this.binaryPoint == that.binaryPoint // TODO: should this be true for unspecified widths?
case _ => false
@@ -1047,8 +1035,8 @@ object FixedPoint {
/** Create an FixedPoint port with specified width and binary position. */
def apply(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
val lit = FPLit(value, width, binaryPoint)
- val newLiteral = new FixedPoint(lit.width, lit.binaryPoint, Some(lit))
- newLiteral.bind(LitBinding())
+ val newLiteral = new FixedPoint(lit.width, lit.binaryPoint)
+ newLiteral.bind(ElementLitBinding(lit))
newLiteral
}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index e85bee42..36aec383 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -364,8 +364,25 @@ abstract class Data extends HasId with NamedComponent {
final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions)
final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions)
- def litArg(): Option[LitArg] = None
+
+ @chiselRuntimeDeprecated
+ @deprecated("Literal accessors on Data are deprecated, a replacement is pending", "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 _ => None
+ }
+ case _ => None
+ }
+ @chiselRuntimeDeprecated
+ @deprecated("Literal accessors on Data are deprecated, a replacement is pending", "chisel3.2")
def litValue(): BigInt = litArg.get.num
+ @chiselRuntimeDeprecated
+ @deprecated("Literal accessors on Data are deprecated, a replacement is pending", "chisel3.2")
def isLit(): Boolean = litArg.isDefined
/** Returns the width, in bits, if currently known.