diff options
| author | ducky | 2018-05-02 11:45:22 -0700 |
|---|---|---|
| committer | Richard Lin | 2018-07-04 18:39:28 -0500 |
| commit | b74034446223db6731c7e4f2eb362b3349efc8be (patch) | |
| tree | 317b55c2c2a11217dc452addb427e57bdac3a2c5 /chiselFrontend | |
| parent | 3d8064a9f2fd49bffb402b91131087c19ca7d6fc (diff) | |
Infrastructure for bundle literals
Diffstat (limited to 'chiselFrontend')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Binding.scala | 9 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 52 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Data.scala | 19 |
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. |
