diff options
| author | ducky | 2018-05-09 17:07:13 -0700 |
|---|---|---|
| committer | Richard Lin | 2018-07-04 18:39:28 -0500 |
| commit | 7834f0ada9f8bcfc28c1d6124f63acdcaa2d4755 (patch) | |
| tree | f086a643a249a04e4929bf12c9d508cf3fea2087 | |
| parent | b74034446223db6731c7e4f2eb362b3349efc8be (diff) | |
work on new style literal accessors
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 } |
