summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorAditya Naik2024-05-03 10:59:45 -0700
committerAditya Naik2024-05-03 10:59:45 -0700
commit878d488a7c8e0d6973de58b3164022c6a102e449 (patch)
treecd081bbcbe3f797f80b10c2d8153da0069750e51 /core/src/main
parent8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff)
Get cleanup to compile
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/scala/chisel3/Aggregate.scala15
-rw-r--r--core/src/main/scala/chisel3/Annotation.scala2
-rw-r--r--core/src/main/scala/chisel3/Bits.scala1299
-rw-r--r--core/src/main/scala/chisel3/BlackBox.scala203
-rw-r--r--core/src/main/scala/chisel3/Data.scala43
-rw-r--r--core/src/main/scala/chisel3/Module.scala309
-rw-r--r--core/src/main/scala/chisel3/ModuleAspect.scala26
-rw-r--r--core/src/main/scala/chisel3/Num.scala1
-rw-r--r--core/src/main/scala/chisel3/RawModule.scala211
-rw-r--r--core/src/main/scala/chisel3/SIntFactory.scala7
-rw-r--r--core/src/main/scala/chisel3/SeqUtils.scala24
-rw-r--r--core/src/main/scala/chisel3/UIntFactory.scala24
-rw-r--r--core/src/main/scala/chisel3/aop/Aspect.scala47
-rw-r--r--core/src/main/scala/chisel3/experimental/Analog.scala3
-rw-r--r--core/src/main/scala/chisel3/experimental/Attach.scala2
-rw-r--r--core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala326
-rw-r--r--core/src/main/scala/chisel3/experimental/dataview/DataView.scala618
-rw-r--r--core/src/main/scala/chisel3/experimental/dataview/package.scala268
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala126
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala117
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala148
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala16
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala25
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala34
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala511
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Underlying.scala14
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/package.scala48
-rw-r--r--core/src/main/scala/chisel3/experimental/package.scala75
-rw-r--r--core/src/main/scala/chisel3/internal/BiConnect.scala69
-rw-r--r--core/src/main/scala/chisel3/internal/Binding.scala10
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala143
-rw-r--r--core/src/main/scala/chisel3/internal/MonoConnect.scala93
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/Converter.scala27
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/IR.scala505
-rw-r--r--core/src/main/scala/chisel3/package.scala27
35 files changed, 69 insertions, 5347 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala
index dbf6969f..5d460c2d 100644
--- a/core/src/main/scala/chisel3/Aggregate.scala
+++ b/core/src/main/scala/chisel3/Aggregate.scala
@@ -3,7 +3,6 @@
package chisel3
import chisel3.experimental.VecLiterals.AddVecLiteralConstructor
-import chisel3.experimental.dataview.{isView, reifySingleData, InvalidViewException}
import scala.collection.immutable.{SeqMap, VectorMap}
import scala.collection.mutable.{HashSet, LinkedHashMap}
@@ -254,20 +253,6 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
requireIsHardware(this, "vec")
requireIsHardware(p, "vec index")
- // Special handling for views
- if (isView(this)) {
- reifySingleData(this) match {
- // Views complicate things a bit, but views that correspond exactly to an identical Vec can just forward the
- // dynamic indexing to the target Vec
- // In theory, we could still do this forwarding if the sample element were different by deriving a DataView
- case Some(target: Vec[T @unchecked])
- if this.length == target.length &&
- this.sample_element.typeEquivalent(target.sample_element) =>
- return target.do_apply(p)
- case _ => throw InvalidViewException("Dynamic indexing of Views is not yet supported")
- }
- }
-
val port = gen
// Reconstruct the resolvedDirection (in Aggregate.bind), since it's not stored.
diff --git a/core/src/main/scala/chisel3/Annotation.scala b/core/src/main/scala/chisel3/Annotation.scala
index c350fb30..d133ab8a 100644
--- a/core/src/main/scala/chisel3/Annotation.scala
+++ b/core/src/main/scala/chisel3/Annotation.scala
@@ -3,7 +3,7 @@
package chisel3.experimental
import scala.language.existentials
-import chisel3.internal.{Builder, InstanceId, LegacyModule}
+import chisel3.internal.{Builder, InstanceId}
import chisel3.{CompileOptions, Data, RawModule}
import firrtl.Transform
import firrtl.annotations._
diff --git a/core/src/main/scala/chisel3/Bits.scala b/core/src/main/scala/chisel3/Bits.scala
index 70704e01..2811f30d 100644
--- a/core/src/main/scala/chisel3/Bits.scala
+++ b/core/src/main/scala/chisel3/Bits.scala
@@ -4,7 +4,6 @@ package chisel3
import scala.language.experimental.macros
-import chisel3.experimental.{FixedPoint, Interval}
import chisel3.internal._
import chisel3.internal.Builder.pushOp
import chisel3.internal.firrtl._
@@ -383,36 +382,6 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
/** @group SourceInfoTransformMacro */
def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt
- /** Reinterpret this $coll as a [[FixedPoint]].
- *
- * @note The value is not guaranteed to be preserved. For example, a [[UInt]] of width 3 and value 7 (0b111) would
- * become a [[FixedPoint]] with value -1. The interpretation of the number is also affected by the specified binary
- * point. '''Caution is advised!'''
- */
- final def asFixedPoint(that: BinaryPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_asFixedPoint(
- that: BinaryPoint
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): FixedPoint = {
- throwException(s"Cannot call .asFixedPoint on $this")
- }
-
- /** Reinterpret cast as a Interval.
- *
- * @note value not guaranteed to be preserved: for example, an UInt of width
- * 3 and value 7 (0b111) would become a FixedInt with value -1, the interpretation
- * of the number is also affected by the specified binary point. Caution advised
- */
- final def asInterval(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg
-
- def do_asInterval(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- throwException(s"Cannot call .asInterval on $this")
- }
-
final def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
width match {
case KnownWidth(1) => this(0)
@@ -820,47 +789,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
pushOp(DefPrim(sourceInfo, SInt(width), AsSIntOp, ref))
override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this
- override def do_asFixedPoint(
- binaryPoint: BinaryPoint
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(
- s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint"
- )
- }
- }
- override def do_asInterval(
- range: IntervalRange = IntervalRange.Unknown
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Interval = {
- (range.lower, range.upper, range.binaryPoint) match {
- case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) =>
- // No mechanism to pass open/close to firrtl so need to handle directly
- val l = lx match {
- case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp)
- case firrtlir.Closed(x) => x
- }
- val u = ux match {
- case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp)
- case firrtlir.Closed(x) => x
- }
- val minBI = (l * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get
- val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get
- pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp)))
- case _ =>
- throwException(s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range")
- }
- }
private[chisel3] override def connectFromBits(
that: Bits
)(
@@ -1112,49 +1041,6 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S
DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
)
override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this
- override def do_asFixedPoint(
- binaryPoint: BinaryPoint
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(
- s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint"
- )
- }
- }
-
- override def do_asInterval(
- range: IntervalRange = IntervalRange.Unknown
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Interval = {
- (range.lower, range.upper, range.binaryPoint) match {
- case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) =>
- // No mechanism to pass open/close to firrtl so need to handle directly
- val l = lx match {
- case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp)
- case firrtlir.Closed(x) => x
- }
- val u = ux match {
- case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp)
- case firrtlir.Closed(x) => x
- }
- //TODO: (chick) Need to determine, what asInterval needs, and why it might need min and max as args -- CAN IT BE UNKNOWN?
- // Angie's operation: Decimal -> Int -> Decimal loses information. Need to be conservative here?
- val minBI = (l * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get
- val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get
- pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp)))
- case _ =>
- throwException(s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range")
- }
- }
private[chisel3] override def connectFromBits(
that: Bits
@@ -1395,7 +1281,6 @@ sealed class Bool() extends UInt(1.W) with Reset {
package experimental {
import chisel3.internal.firrtl.BinaryPoint
- import chisel3.internal.requireIsHardware // Fix ambiguous import
/** Chisel types that have binary points support retrieving
* literal values as `Double` or `BigDecimal`
@@ -1434,1188 +1319,4 @@ package experimental {
*/
def litToBigDecimal: BigDecimal = litToBigDecimalOption.get
}
-
- /** 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.
- *
- * IMPORTANT: The API provided here is experimental and may change in the future.
- *
- * @param width bit width of the fixed point number
- * @param binaryPoint the position of the binary point with respect to the right most bit of the width currently this
- * should be positive but it is hoped to soon support negative points and thus use this field as a
- * simple exponent
- * @define coll [[FixedPoint]]
- * @define numType $coll
- * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`.
- * @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]
- with HasBinaryPoint {
-
- override def toString: String = {
- litToDoubleOption match {
- case Some(value) => s"FixedPoint$width$binaryPoint($value)"
- case _ => stringAccessor(s"FixedPoint$width$binaryPoint")
- }
- }
-
- private[chisel3] 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
- }
-
- private[chisel3] override def cloneTypeWidth(w: Width): this.type =
- new FixedPoint(w, binaryPoint).asInstanceOf[this.type]
-
- override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit =
- that match {
- case _: FixedPoint | DontCare => super.connect(that)
- case _ => this.badConnect(that)
- }
-
- /** Unary negation (expanding width)
- *
- * @return a hardware $coll equal to zero minus this $coll
- * $expandingWidth
- * @group Arithmetic
- */
- final def unary_- : FixedPoint = macro SourceInfoTransform.noArg
-
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- final def unary_-(dummy: Int*): FixedPoint = macro SourceInfoTransform.noArgDummy
-
- /** Unary negation (constant width)
- *
- * @return a hardware $coll equal to zero minus `this` shifted right by one
- * $constantWidth
- * @group Arithmetic
- */
- final def unary_-% : FixedPoint = macro SourceInfoTransform.noArg
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- final def unary_-%(dummy: Int*): FixedPoint = macro SourceInfoTransform.noArgDummy
-
- /** @group SourceInfoTransformMacro */
- def do_unary_-(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- FixedPoint.fromBigInt(0) - this
-
- /** @group SourceInfoTransformMacro */
- def do_unary_-%(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- FixedPoint.fromBigInt(0) -% this
-
- /** add (default - no growth) operator */
- override def do_+(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- this +% that
-
- /** subtract (default - no growth) operator */
- override def do_-(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- this -% that
- override def do_*(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that.width, this.binaryPoint + that.binaryPoint), TimesOp, that)
- override def do_/(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"division is illegal on FixedPoint types")
- override def do_%(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"mod is illegal on FixedPoint types")
-
- /** Multiplication operator
- *
- * @param that a hardware [[UInt]]
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def *(that: UInt): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_*(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that)
-
- /** Multiplication operator
- *
- * @param that a hardware [[SInt]]
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def *(that: SInt): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_*(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that)
-
- /** Addition operator (expanding width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def +&(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Addition operator (constant width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that` shifted right by one
- * $maxWidth
- * @group Arithmetic
- */
- final def +%(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (increasing width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def -&(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (constant width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that` shifted right by one
- * $maxWidth
- * @group Arithmetic
- */
- final def -%(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_+&(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- (this.width, that.width, this.binaryPoint, that.binaryPoint) match {
- case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) =>
- val thisIntWidth = thisWidth - thisBP
- val thatIntWidth = thatWidth - thatBP
- val newBinaryPoint = thisBP.max(thatBP)
- val newWidth = (thisIntWidth.max(thatIntWidth)) + newBinaryPoint + 1
- binop(sourceInfo, FixedPoint(newWidth.W, newBinaryPoint.BP), AddOp, that)
- case _ =>
- val newBinaryPoint = this.binaryPoint.max(that.binaryPoint)
- binop(sourceInfo, FixedPoint(UnknownWidth(), newBinaryPoint), AddOp, that)
- }
- }
-
- /** @group SourceInfoTransformMacro */
- def do_+%(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this +& that).tail(1).asFixedPoint(this.binaryPoint.max(that.binaryPoint))
-
- /** @group SourceInfoTransformMacro */
- def do_-&(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- (this.width, that.width, this.binaryPoint, that.binaryPoint) match {
- case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) =>
- val thisIntWidth = thisWidth - thisBP
- val thatIntWidth = thatWidth - thatBP
- val newBinaryPoint = thisBP.max(thatBP)
- val newWidth = (thisIntWidth.max(thatIntWidth)) + newBinaryPoint + 1
- binop(sourceInfo, FixedPoint(newWidth.W, newBinaryPoint.BP), SubOp, that)
- case _ =>
- val newBinaryPoint = this.binaryPoint.max(that.binaryPoint)
- binop(sourceInfo, FixedPoint(UnknownWidth(), newBinaryPoint), SubOp, that)
- }
- }
-
- /** @group SourceInfoTransformMacro */
- def do_-%(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this -& that).tail(1).asFixedPoint(this.binaryPoint.max(that.binaryPoint))
-
- /** Bitwise and operator
- *
- * @param that a hardware $coll
- * @return the bitwise and of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def &(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Bitwise or operator
- *
- * @param that a hardware $coll
- * @return the bitwise or of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def |(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Bitwise exclusive or (xor) operator
- *
- * @param that a hardware $coll
- * @return the bitwise xor of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def ^(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_&(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"And is illegal between $this and $that")
-
- /** @group SourceInfoTransformMacro */
- def do_|(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"Or is illegal between $this and $that")
-
- /** @group SourceInfoTransformMacro */
- def do_^(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"Xor is illegal between $this and $that")
-
- final def setBinaryPoint(that: Int): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_setBinaryPoint(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- this.binaryPoint match {
- case KnownBinaryPoint(value) =>
- binop(sourceInfo, FixedPoint(this.width + (that - value), KnownBinaryPoint(that)), SetBinaryPoint, that)
- case _ =>
- binop(sourceInfo, FixedPoint(UnknownWidth(), KnownBinaryPoint(that)), SetBinaryPoint, that)
- }
-
- /** @group SourceInfoTransformMacro */
- def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"Not is illegal on $this")
-
- override def do_<(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, LessOp, that)
- override def do_>(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, GreaterOp, that)
- override def do_<=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, LessEqOp, that)
- override def do_>=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, GreaterEqOp, that)
-
- final def !=(that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
-
- /** Dynamic not equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is not equal to `that`
- * @group Comparison
- */
- final def =/=(that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
-
- /** Dynamic equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is equal to `that`
- * @group Comparison
- */
- final def ===(that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_!=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, NotEqualOp, that)
-
- /** @group SourceInfoTransformMacro */
- def do_=/=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, NotEqualOp, that)
-
- /** @group SourceInfoTransformMacro */
- def do_===(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, EqualOp, that)
-
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- // TODO: remove this once we have CompileOptions threaded through the macro system.
- import chisel3.ExplicitCompileOptions.NotStrict
- Mux(this < 0.F(0.BP), 0.F(0.BP) - this, this)
- }
-
- override def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, validateShiftAmount(that))
- override def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this << castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint)
- override def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width.dynamicShiftLeft(that.width), this.binaryPoint), DynamicShiftLeftOp, that)
- override def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(
- sourceInfo,
- FixedPoint(this.width.shiftRight(that), this.binaryPoint),
- ShiftRightOp,
- validateShiftAmount(that)
- )
- override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this >> castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint)
- override def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width, this.binaryPoint), DynamicShiftRightOp, that)
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp(
- DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
- )
- override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = pushOp(
- DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref)
- )
-
- override def do_asFixedPoint(
- binaryPoint: BinaryPoint
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(
- s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint"
- )
- }
- }
-
- def do_asInterval(
- binaryPoint: BinaryPoint
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Interval = {
- throwException(s"cannot call $this.asInterval(binaryPoint=$binaryPoint), you must specify a range")
- }
-
- override def do_asInterval(
- range: IntervalRange = IntervalRange.Unknown
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Interval = {
- (range.lower, range.upper, range.binaryPoint) match {
- case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) =>
- // No mechanism to pass open/close to firrtl so need to handle directly
- val l = lx match {
- case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp)
- case firrtlir.Closed(x) => x
- }
- val u = ux match {
- case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp)
- case firrtlir.Closed(x) => x
- }
- val minBI = (l * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get
- val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get
- pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp)))
- case _ =>
- throwException(s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range")
- }
- }
-
- private[chisel3] override def connectFromBits(
- that: Bits
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ) {
- // TODO: redefine as just asFixedPoint on that, where FixedPoint.asFixedPoint just works.
- this := (that match {
- case fp: FixedPoint => fp.asSInt.asFixedPoint(this.binaryPoint)
- case _ => that.asFixedPoint(this.binaryPoint)
- })
- }
- }
-
- /** Use PrivateObject to force users to specify width and binaryPoint by name
- */
- sealed trait PrivateType
- private case object PrivateObject extends PrivateType
-
- /**
- * Factory and convenience methods for the FixedPoint class
- * IMPORTANT: The API provided here is experimental and may change in the future.
- */
- object FixedPoint extends NumObject {
-
- import FixedPoint.Implicits._
-
- /** Create an FixedPoint type with inferred width. */
- def apply(): FixedPoint = apply(Width(), BinaryPoint())
-
- /** Create an FixedPoint type or port with fixed width. */
- def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint)
-
- /** Create an FixedPoint literal with inferred width from BigInt.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigInt(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- apply(value, width, binaryPoint)
- }
-
- /** Create an FixedPoint literal with inferred width from BigInt.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigInt(value: BigInt, binaryPoint: BinaryPoint = 0.BP): FixedPoint = {
- apply(value, Width(), binaryPoint)
- }
-
- /** Create an FixedPoint literal with inferred width from BigInt.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigInt(value: BigInt, width: Int, binaryPoint: Int): FixedPoint =
- if (width == -1) {
- apply(value, Width(), BinaryPoint(binaryPoint))
- } else {
- apply(value, Width(width), BinaryPoint(binaryPoint))
- }
-
- /** Create an FixedPoint literal with inferred width from Double.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- fromBigInt(
- 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 = {
- val lit = FPLit(value, width, binaryPoint)
- val newLiteral = new FixedPoint(lit.width, lit.binaryPoint)
- // Ensure we have something capable of generating a name.
- lit.bindLitArg(newLiteral)
- }
-
- object Implicits {
-
- implicit class fromDoubleToLiteral(double: Double) {
- def F(binaryPoint: BinaryPoint): FixedPoint = {
- FixedPoint.fromDouble(double, Width(), binaryPoint)
- }
-
- def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- 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)
- }
- }
- }
- }
-
- /**
- * A sealed class representing a fixed point number that has a range, an additional
- * parameter that can determine a minimum and maximum supported value.
- * The range can be used to reduce the required widths particularly in primitive
- * operations with other Intervals, the canonical example being
- * {{{
- * val one = 1.I
- * val six = Seq.fill(6)(one).reduce(_ + _)
- * }}}
- * A UInt computed in this way would require a [[Width]]
- * binary point
- * The width and binary point may be inferred.
- *
- * IMPORTANT: The API provided here is experimental and may change in the future.
- *
- * @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]
- with HasBinaryPoint {
-
- override def toString: String = {
- litOption match {
- case Some(value) => s"Interval$width($value)"
- case _ => stringAccessor(s"Interval$width")
- }
- }
-
- private[chisel3] override def cloneTypeWidth(w: Width): this.type =
- new Interval(range).asInstanceOf[this.type]
-
- def toType: String = {
- val zdec1 = """([+\-]?[0-9]\d*)(\.[0-9]*[1-9])(0*)""".r
- val zdec2 = """([+\-]?[0-9]\d*)(\.0*)""".r
- val dec = """([+\-]?[0-9]\d*)(\.[0-9]\d*)""".r
- val int = """([+\-]?[0-9]\d*)""".r
- def dec2string(v: BigDecimal): String = v.toString match {
- case zdec1(x, y, z) => x + y
- case zdec2(x, y) => x
- case other => other
- }
-
- val lowerString = range.lower match {
- case firrtlir.Open(l) => s"(${dec2string(l)}, "
- case firrtlir.Closed(l) => s"[${dec2string(l)}, "
- case firrtlir.UnknownBound => s"[?, "
- case _ => s"[?, "
- }
- val upperString = range.upper match {
- case firrtlir.Open(u) => s"${dec2string(u)})"
- case firrtlir.Closed(u) => s"${dec2string(u)}]"
- case firrtlir.UnknownBound => s"?]"
- case _ => s"?]"
- }
- val bounds = lowerString + upperString
-
- val pointString = range.binaryPoint match {
- case KnownBinaryPoint(i) => "." + i.toString
- case _ => ""
- }
- "Interval" + bounds + pointString
- }
-
- private[chisel3] override def typeEquivalent(that: Data): Boolean =
- that.isInstanceOf[Interval] && this.width == that.width
-
- def binaryPoint: BinaryPoint = range.binaryPoint
-
- override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = {
- that match {
- case _: Interval | DontCare => super.connect(that)
- case _ => this.badConnect(that)
- }
- }
-
- final def unary_- : Interval = macro SourceInfoTransform.noArg
-
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- final def unary_-(dummy: Int*): Interval = macro SourceInfoTransform.noArgDummy
-
- final def unary_-% : Interval = macro SourceInfoTransform.noArg
-
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- final def unary_-%(dummy: Int*): Interval = macro SourceInfoTransform.noArgDummy
-
- /** @group SourceInfoTransformMacro */
- def do_unary_-(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- Interval.Zero - this
- }
- def do_unary_-%(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- Interval.Zero -% this
- }
-
- /** add (default - growing) operator */
- override def do_+(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- this +& that
-
- /** subtract (default - growing) operator */
- override def do_-(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- this -& that
- override def do_*(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- binop(sourceInfo, Interval(this.range * that.range), TimesOp, that)
-
- override def do_/(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- throwException(s"division is illegal on Interval types")
- override def do_%(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- throwException(s"mod is illegal on Interval types")
-
- /** add (width +1) operator */
- final def +&(that: Interval): Interval = macro SourceInfoTransform.thatArg
-
- /** add (no growth) operator */
- final def +%(that: Interval): Interval = macro SourceInfoTransform.thatArg
-
- /** subtract (width +1) operator */
- final def -&(that: Interval): Interval = macro SourceInfoTransform.thatArg
-
- /** subtract (no growth) operator */
- final def -%(that: Interval): Interval = macro SourceInfoTransform.thatArg
-
- def do_+&(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- binop(sourceInfo, Interval(this.range +& that.range), AddOp, that)
- }
-
- def do_+%(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- throwException(s"Non-growing addition is not supported on Intervals: ${sourceInfo}")
- }
-
- def do_-&(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- binop(sourceInfo, Interval(this.range -& that.range), SubOp, that)
- }
-
- def do_-%(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- throwException(s"Non-growing subtraction is not supported on Intervals: ${sourceInfo}, try squeeze")
- }
-
- final def &(that: Interval): Interval = macro SourceInfoTransform.thatArg
- final def |(that: Interval): Interval = macro SourceInfoTransform.thatArg
- final def ^(that: Interval): Interval = macro SourceInfoTransform.thatArg
-
- def do_&(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- throwException(s"And is illegal between $this and $that")
- def do_|(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- throwException(s"Or is illegal between $this and $that")
- def do_^(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- throwException(s"Xor is illegal between $this and $that")
-
- final def setPrecision(that: Int): Interval = macro SourceInfoTransform.thatArg
-
- // Precision change changes range -- see firrtl PrimOps (requires floor)
- // aaa.bbb -> aaa.bb for sbp(2)
- def do_setPrecision(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- val newBinaryPoint = BinaryPoint(that)
- val newIntervalRange = this.range.setPrecision(newBinaryPoint)
- binop(sourceInfo, Interval(newIntervalRange), SetBinaryPoint, that)
- }
-
- /** Increase the precision of this Interval, moves the binary point to the left.
- * aaa.bbb -> aaa.bbb00
- * @param that how many bits to shift binary point
- * @return
- */
- final def increasePrecision(that: Int): Interval = macro SourceInfoTransform.thatArg
-
- def do_increasePrecision(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- assert(that > 0, s"Must increase precision by an integer greater than zero.")
- val newBinaryPoint = BinaryPoint(that)
- val newIntervalRange = this.range.incPrecision(newBinaryPoint)
- binop(sourceInfo, Interval(newIntervalRange), IncreasePrecision, that)
- }
-
- /** Decrease the precision of this Interval, moves the binary point to the right.
- * aaa.bbb -> aaa.b
- *
- * @param that number of bits to move binary point
- * @return
- */
- final def decreasePrecision(that: Int): Interval = macro SourceInfoTransform.thatArg
-
- def do_decreasePrecision(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- assert(that > 0, s"Must decrease precision by an integer greater than zero.")
- val newBinaryPoint = BinaryPoint(that)
- val newIntervalRange = this.range.decPrecision(newBinaryPoint)
- binop(sourceInfo, Interval(newIntervalRange), DecreasePrecision, that)
- }
-
- /** Returns this wire bitwise-inverted. */
- def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- throwException(s"Not is illegal on $this")
-
- override def do_<(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, LessOp, that)
- override def do_>(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, GreaterOp, that)
- override def do_<=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, LessEqOp, that)
- override def do_>=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, GreaterEqOp, that)
-
- final def !=(that: Interval): Bool = macro SourceInfoTransform.thatArg
- final def =/=(that: Interval): Bool = macro SourceInfoTransform.thatArg
- final def ===(that: Interval): Bool = macro SourceInfoTransform.thatArg
-
- def do_!=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, NotEqualOp, that)
- def do_=/=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, NotEqualOp, that)
- def do_===(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- compop(sourceInfo, EqualOp, that)
-
- // final def abs(): UInt = macro SourceInfoTransform.noArgDummy
-
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- Mux(this < Interval.Zero, (Interval.Zero - this), this)
- }
-
- override def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- binop(sourceInfo, Interval(this.range << that), ShiftLeftOp, that)
-
- override def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- do_<<(that.toInt)
-
- override def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- binop(sourceInfo, Interval(this.range << that), DynamicShiftLeftOp, that)
- }
-
- override def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- binop(sourceInfo, Interval(this.range >> that), ShiftRightOp, that)
- }
-
- override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval =
- do_>>(that.toInt)
-
- override def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- binop(sourceInfo, Interval(this.range >> that), DynamicShiftRightOp, that)
- }
-
- /**
- * Squeeze returns the intersection of the ranges this interval and that Interval
- * Ignores binary point of argument
- * Treat as an unsafe cast; gives undefined behavior if this signal's value is outside of the resulting range
- * Adds no additional hardware; this strictly an unsafe type conversion to use at your own risk
- * @param that
- * @return
- */
- final def squeeze(that: Interval): Interval = macro SourceInfoTransform.thatArg
- def do_squeeze(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- val other = that
- requireIsHardware(this, s"'this' ($this)")
- requireIsHardware(other, s"'other' ($other)")
- pushOp(DefPrim(sourceInfo, Interval(this.range.squeeze(that.range)), SqueezeOp, this.ref, other.ref))
- }
-
- /**
- * Squeeze returns the intersection of the ranges this interval and that UInt
- * Currently, that must have a defined width
- * Treat as an unsafe cast; gives undefined behavior if this signal's value is outside of the resulting range
- * Adds no additional hardware; this strictly an unsafe type conversion to use at your own risk
- * @param that an UInt whose properties determine the squeezing
- * @return
- */
- final def squeeze(that: UInt): Interval = macro SourceInfoTransform.thatArg
- def do_squeeze(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- that.widthOption match {
- case Some(w) =>
- do_squeeze(Wire(Interval(IntervalRange(that.width, BinaryPoint(0)))))
- case _ =>
- throwException(s"$this.squeeze($that) requires an UInt argument with a known width")
- }
- }
-
- /**
- * Squeeze returns the intersection of the ranges this interval and that SInt
- * Currently, that must have a defined width
- * Treat as an unsafe cast; gives undefined behavior if this signal's value is outside of the resulting range
- * Adds no additional hardware; this strictly an unsafe type conversion to use at your own risk
- * @param that an SInt whose properties determine the squeezing
- * @return
- */
- final def squeeze(that: SInt): Interval = macro SourceInfoTransform.thatArg
- def do_squeeze(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- that.widthOption match {
- case Some(w) =>
- do_squeeze(Wire(Interval(IntervalRange(that.width, BinaryPoint(0)))))
- case _ =>
- throwException(s"$this.squeeze($that) requires an SInt argument with a known width")
- }
- }
-
- /**
- * Squeeze returns the intersection of the ranges this interval and that IntervalRange
- * Ignores binary point of argument
- * Treat as an unsafe cast; gives undefined behavior if this signal's value is outside of the resulting range
- * Adds no additional hardware; this strictly an unsafe type conversion to use at your own risk
- * @param that an Interval whose properties determine the squeezing
- * @return
- */
- final def squeeze(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg
- def do_squeeze(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- val intervalLitOpt = Interval.getSmallestLegalLit(that)
- val intervalLit = intervalLitOpt.getOrElse(
- throwException(s"$this.squeeze($that) requires an Interval range with known lower and upper bounds")
- )
- do_squeeze(intervalLit)
- }
-
- /**
- * Wrap the value of this [[Interval]] into the range of a different Interval with a presumably smaller range.
- * Ignores binary point of argument
- * Errors if requires wrapping more than once
- * @param that
- * @return
- */
- final def wrap(that: Interval): Interval = macro SourceInfoTransform.thatArg
-
- def do_wrap(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- val other = that
- requireIsHardware(this, s"'this' ($this)")
- requireIsHardware(other, s"'other' ($other)")
- pushOp(DefPrim(sourceInfo, Interval(this.range.wrap(that.range)), WrapOp, this.ref, other.ref))
- }
-
- /**
- * Wrap this interval into the range determined by that UInt
- * Errors if requires wrapping more than once
- * @param that an UInt whose properties determine the wrap
- * @return
- */
- final def wrap(that: UInt): Interval = macro SourceInfoTransform.thatArg
- def do_wrap(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- that.widthOption match {
- case Some(w) =>
- val u = BigDecimal(BigInt(1) << w) - 1
- do_wrap(0.U.asInterval(IntervalRange(firrtlir.Closed(0), firrtlir.Closed(u), BinaryPoint(0))))
- case _ =>
- throwException(s"$this.wrap($that) requires UInt with known width")
- }
- }
-
- /**
- * Wrap this interval into the range determined by an SInt
- * Errors if requires wrapping more than once
- * @param that an SInt whose properties determine the bounds of the wrap
- * @return
- */
- final def wrap(that: SInt): Interval = macro SourceInfoTransform.thatArg
- def do_wrap(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- that.widthOption match {
- case Some(w) =>
- val l = -BigDecimal(BigInt(1) << (that.getWidth - 1))
- val u = BigDecimal(BigInt(1) << (that.getWidth - 1)) - 1
- do_wrap(Wire(Interval(IntervalRange(firrtlir.Closed(l), firrtlir.Closed(u), BinaryPoint(0)))))
- case _ =>
- throwException(s"$this.wrap($that) requires SInt with known width")
- }
- }
-
- /**
- * Wrap this interval into the range determined by an IntervalRange
- * Adds hardware to change values outside of wrapped range to be at the boundary
- * Errors if requires wrapping more than once
- * Ignores binary point of argument
- * @param that an Interval whose properties determine the bounds of the wrap
- * @return
- */
- final def wrap(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg
- def do_wrap(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- (that.lowerBound, that.upperBound) match {
- case (lower: firrtlconstraint.IsKnown, upperBound: firrtlconstraint.IsKnown) =>
- do_wrap(0.U.asInterval(IntervalRange(that.lowerBound, that.upperBound, BinaryPoint(0))))
- case _ =>
- throwException(s"$this.wrap($that) requires Interval argument with known lower and upper bounds")
- }
- }
-
- /**
- * Clip this interval into the range determined by argument's range
- * Adds hardware to change values outside of clipped range to be at the boundary
- * Ignores binary point of argument
- * @param that an Interval whose properties determine the clipping
- * @return
- */
- final def clip(that: Interval): Interval = macro SourceInfoTransform.thatArg
- def do_clip(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- binop(sourceInfo, Interval(this.range.clip(that.range)), ClipOp, that)
- }
-
- /**
- * Clip this interval into the range determined by argument's range
- * Adds hardware to change values outside of clipped range to be at the boundary
- * @param that an UInt whose width determines the clipping
- * @return
- */
- final def clip(that: UInt): Interval = macro SourceInfoTransform.thatArg
- def do_clip(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- require(that.widthKnown, "UInt clip width must be known")
- val u = BigDecimal(BigInt(1) << that.getWidth) - 1
- do_clip(Wire(Interval(IntervalRange(firrtlir.Closed(0), firrtlir.Closed(u), BinaryPoint(0)))))
- }
-
- /**
- * Clip this interval into the range determined by argument's range
- * Adds hardware to move values outside of clipped range to the boundary
- * @param that an SInt whose width determines the clipping
- * @return
- */
- final def clip(that: SInt): Interval = macro SourceInfoTransform.thatArg
- def do_clip(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- require(that.widthKnown, "SInt clip width must be known")
- val l = -BigDecimal(BigInt(1) << (that.getWidth - 1))
- val u = BigDecimal(BigInt(1) << (that.getWidth - 1)) - 1
- do_clip(Wire(Interval(IntervalRange(firrtlir.Closed(l), firrtlir.Closed(u), BinaryPoint(0)))))
- }
-
- /**
- * Clip this interval into the range determined by argument's range
- * Adds hardware to move values outside of clipped range to the boundary
- * Ignores binary point of argument
- * @param that an SInt whose width determines the clipping
- * @return
- */
- final def clip(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg
- def do_clip(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- (that.lowerBound, that.upperBound) match {
- case (lower: firrtlconstraint.IsKnown, upperBound: firrtlconstraint.IsKnown) =>
- do_clip(0.U.asInterval(IntervalRange(that.lowerBound, that.upperBound, BinaryPoint(0))))
- case _ =>
- throwException(s"$this.clip($that) requires Interval argument with known lower and upper bounds")
- }
- }
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
- }
- override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = {
- pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref))
- }
-
- override def do_asFixedPoint(
- binaryPoint: BinaryPoint
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(
- s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint"
- )
- }
- }
-
- // TODO: intervals chick INVALID -- not enough args
- def do_asInterval(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = {
- pushOp(DefPrim(sourceInfo, Interval(this.range), AsIntervalOp, ref))
- throwException(s"($this).asInterval must specify arguments INVALID")
- }
-
- // TODO:(chick) intervals chick looks like this is wrong and only for FP?
- def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
- /*val res = Wire(this, null).asInstanceOf[this.type]
- res := (that match {
- case fp: FixedPoint => fp.asSInt.asFixedPoint(this.binaryPoint)
- case _ => that.asFixedPoint(this.binaryPoint)
- })
- res*/
- throwException("fromBits INVALID for intervals")
- }
-
- private[chisel3] override def connectFromBits(
- that: Bits
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ) {
- this := that.asInterval(this.range)
- }
- }
-
- /** Use PrivateObject to force users to specify width and binaryPoint by name
- */
-
- /**
- * Factory and convenience methods for the Interval class
- * IMPORTANT: The API provided here is experimental and may change in the future.
- */
- object Interval extends NumObject {
-
- /** Create an Interval type with inferred width and binary point. */
- def apply(): Interval = Interval(range"[?,?]")
-
- /** Create an Interval type with specified width. */
- def apply(binaryPoint: BinaryPoint): Interval = {
- val binaryPointString = binaryPoint match {
- case KnownBinaryPoint(value) => s"$value"
- case _ => s""
- }
- Interval(range"[?,?].$binaryPointString")
- }
-
- /** Create an Interval type with specified width. */
- def apply(width: Width): Interval = Interval(width, 0.BP)
-
- /** Create an Interval type with specified width and binary point */
- def apply(width: Width, binaryPoint: BinaryPoint): Interval = {
- Interval(IntervalRange(width, binaryPoint))
- }
-
- /** Create an Interval type with specified range.
- * @param range defines the properties
- */
- def apply(range: IntervalRange): Interval = {
- new Interval(range)
- }
-
- /** Creates a Interval connected to a Interval literal with the value zero */
- def Zero: Interval = Lit(0, 1.W, 0.BP)
-
- /** Creates an Interval zero that supports the given range
- * Useful for creating a Interval register that has a desired number of bits
- * {{{
- * val myRegister = RegInit(Interval.Zero(r"[0,12]")
- * }}}
- * @param range
- * @return
- */
- def Zero(range: IntervalRange): Interval = Lit(0, range)
-
- /** Make an interval from this BigInt, the BigInt is treated as bits
- * So lower binaryPoint number of bits will treated as mantissa
- *
- * @param value
- * @param width
- * @param binaryPoint
- * @return
- */
- def fromBigInt(value: BigInt, width: Width = Width(), binaryPoint: BinaryPoint = 0.BP): Interval = {
- Interval.Lit(value, Width(), binaryPoint)
- }
-
- /** Create an Interval literal with inferred width from Double.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromDouble(
- value: Double,
- dummy: PrivateType = PrivateObject,
- width: Width,
- binaryPoint: BinaryPoint
- ): Interval = {
- fromBigInt(
- toBigInt(value, binaryPoint),
- width = width,
- binaryPoint = binaryPoint
- )
- }
-
- /** Create an Interval literal with inferred width from Double.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigDecimal(
- value: Double,
- dummy: PrivateType = PrivateObject,
- width: Width,
- binaryPoint: BinaryPoint
- ): Interval = {
- fromBigInt(
- toBigInt(value, binaryPoint),
- width = width,
- binaryPoint = binaryPoint
- )
- }
-
- protected[chisel3] def Lit(value: BigInt, width: Width, binaryPoint: BinaryPoint): Interval = {
- width match {
- case KnownWidth(w) =>
- if (value >= 0 && value.bitLength >= w || value < 0 && value.bitLength > w) {
- throw new ChiselException(
- s"Error literal interval value $value is too many bits for specified width $w"
- )
- }
- case _ =>
- }
- val lit = IntervalLit(value, width, binaryPoint)
- val bound = firrtlir.Closed(Interval.toBigDecimal(value, binaryPoint.asInstanceOf[KnownBinaryPoint].value))
- val result = new Interval(IntervalRange(bound, bound, binaryPoint))
- lit.bindLitArg(result)
- }
-
- protected[chisel3] def Lit(value: BigInt, range: IntervalRange): Interval = {
- val lit = IntervalLit(value, range.getWidth, range.binaryPoint)
- val bigDecimal = BigDecimal(value) / (1 << lit.binaryPoint.get)
- val inRange = (range.lowerBound, range.upperBound) match {
- case (firrtlir.Closed(l), firrtlir.Closed(u)) => l <= bigDecimal && bigDecimal <= u
- case (firrtlir.Closed(l), firrtlir.Open(u)) => l <= bigDecimal && bigDecimal < u
- case (firrtlir.Open(l), firrtlir.Closed(u)) => l < bigDecimal && bigDecimal <= u
- case (firrtlir.Open(l), firrtlir.Open(u)) => l < bigDecimal && bigDecimal < u
- }
- if (!inRange) {
- throw new ChiselException(
- s"Error literal interval value $bigDecimal is not contained in specified range $range"
- )
- }
- val result = Interval(range)
- lit.bindLitArg(result)
- }
-
- /**
- * 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
- * @return
- */
- def getSmallestLegalLit(range: IntervalRange): Option[Interval] = {
- val bp = range.binaryPoint
- range.lowerBound match {
- case firrtlir.Closed(lowerBound) =>
- Some(Interval.Lit(toBigInt(lowerBound.toDouble, bp), width = range.getWidth, bp))
- case firrtlir.Open(lowerBound) =>
- Some(Interval.Lit(toBigInt(lowerBound.toDouble, bp) + BigInt(1), width = range.getWidth, bp))
- case _ =>
- None
- }
- }
-
- /**
- * 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
- * @return
- */
- def getLargestLegalLit(range: IntervalRange): Option[Interval] = {
- val bp = range.binaryPoint
- range.upperBound match {
- case firrtlir.Closed(upperBound) =>
- Some(Interval.Lit(toBigInt(upperBound.toDouble, bp), width = range.getWidth, bp))
- case firrtlir.Open(upperBound) =>
- Some(Interval.Lit(toBigInt(upperBound.toDouble, bp) - BigInt(1), width = range.getWidth, bp))
- case _ =>
- None
- }
- }
-
- /** Contains the implicit classes used to provide the .I methods to create intervals
- * from the standard numberic types.
- * {{{
- * val x = 7.I
- * val y = 7.5.I(4.BP)
- * }}}
- */
- object Implicits {
- implicit class fromBigIntToLiteralInterval(bigInt: BigInt) {
- def I: Interval = {
- Interval.Lit(bigInt, width = Width(), 0.BP)
- }
-
- def I(binaryPoint: BinaryPoint): Interval = {
- Interval.Lit(bigInt, width = Width(), binaryPoint = binaryPoint)
- }
-
- def I(width: Width, binaryPoint: BinaryPoint): Interval = {
- Interval.Lit(bigInt, width, binaryPoint)
- }
-
- def I(range: IntervalRange): Interval = {
- Interval.Lit(bigInt, range)
- }
- }
-
- implicit class fromIntToLiteralInterval(int: Int) extends fromBigIntToLiteralInterval(int)
- implicit class fromLongToLiteralInterval(long: Long) extends fromBigIntToLiteralInterval(long)
-
- implicit class fromBigDecimalToLiteralInterval(bigDecimal: BigDecimal) {
- def I: Interval = {
- Interval.Lit(Interval.toBigInt(bigDecimal, 0.BP), width = Width(), 0.BP)
- }
-
- def I(binaryPoint: BinaryPoint): Interval = {
- Interval.Lit(Interval.toBigInt(bigDecimal, binaryPoint), width = Width(), binaryPoint = binaryPoint)
- }
-
- def I(width: Width, binaryPoint: BinaryPoint): Interval = {
- Interval.Lit(Interval.toBigInt(bigDecimal, binaryPoint), width, binaryPoint)
- }
-
- def I(range: IntervalRange): Interval = {
- Interval.Lit(Interval.toBigInt(bigDecimal, range.binaryPoint), range)
- }
- }
-
- implicit class fromDoubleToLiteralInterval(double: Double)
- extends fromBigDecimalToLiteralInterval(BigDecimal(double))
- }
- }
}
diff --git a/core/src/main/scala/chisel3/BlackBox.scala b/core/src/main/scala/chisel3/BlackBox.scala
deleted file mode 100644
index c3cb3e66..00000000
--- a/core/src/main/scala/chisel3/BlackBox.scala
+++ /dev/null
@@ -1,203 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3
-
-import chisel3.experimental.{BaseModule, Param}
-import chisel3.internal.BaseBlackBox
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.throwException
-import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo}
-import scala.annotation.nowarn
-
-package internal {
-
- private[chisel3] abstract class BaseBlackBox extends BaseModule
-
-}
-
-package experimental {
-
- /** Parameters for BlackBoxes */
- sealed abstract class Param
- case class IntParam(value: BigInt) extends Param
- case class DoubleParam(value: Double) extends Param
- case class StringParam(value: String) extends Param
-
- /** Unquoted String */
- case class RawParam(value: String) extends Param
-
- /** Defines a black box, which is a module that can be referenced from within
- * Chisel, but is not defined in the emitted Verilog. Useful for connecting
- * to RTL modules defined outside Chisel.
- *
- * A variant of BlackBox, this has a more consistent naming scheme in allowing
- * multiple top-level IO and does not drop the top prefix.
- *
- * @example
- * Some design require a differential input clock to clock the all design.
- * With the xilinx FPGA for example, a Verilog template named IBUFDS must be
- * integrated to use differential input:
- * {{{
- * IBUFDS #(.DIFF_TERM("TRUE"),
- * .IOSTANDARD("DEFAULT")) ibufds (
- * .IB(ibufds_IB),
- * .I(ibufds_I),
- * .O(ibufds_O)
- * );
- * }}}
- *
- * To instantiate it, a BlackBox can be used like following:
- * {{{
- * import chisel3._
- * import chisel3.experimental._
- *
- * // Example with Xilinx differential buffer IBUFDS
- * class IBUFDS extends ExtModule(Map("DIFF_TERM" -> "TRUE", // Verilog parameters
- * "IOSTANDARD" -> "DEFAULT"
- * )) {
- * val O = IO(Output(Clock()))
- * val I = IO(Input(Clock()))
- * val IB = IO(Input(Clock()))
- * }
- * }}}
- * @note The parameters API is experimental and may change
- */
- @nowarn("msg=class Port") // delete when Port becomes private
- abstract class ExtModule(val params: Map[String, Param] = Map.empty[String, Param]) extends BaseBlackBox {
- private[chisel3] override def generateComponent(): Option[Component] = {
- require(!_closed, "Can't generate module more than once")
- _closed = true
-
- val names = nameIds(classOf[ExtModule])
-
- // Ports are named in the same way as regular Modules
- namePorts(names)
-
- // All suggestions are in, force names to every node.
- // While BlackBoxes are not supposed to have an implementation, we still need to call
- // _onModuleClose on all nodes (for example, Aggregates use it for recursive naming).
- for (id <- getIds) {
- id._onModuleClose
- }
-
- closeUnboundIds(names)
-
- val firrtlPorts = getModulePorts.map { port => Port(port, port.specifiedDirection) }
- val component = DefBlackBox(this, name, firrtlPorts, SpecifiedDirection.Unspecified, params)
- _component = Some(component)
- _component
- }
-
- private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
-
- if (!parentCompileOptions.explicitInvalidate) {
- for (x <- getModulePorts) {
- pushCommand(DefInvalid(sourceInfo, x.ref))
- }
- }
- }
- }
-}
-
-/** Defines a black box, which is a module that can be referenced from within
- * Chisel, but is not defined in the emitted Verilog. Useful for connecting
- * to RTL modules defined outside Chisel.
- *
- * @example
- * Some design require a differential input clock to clock the all design.
- * With the xilinx FPGA for example, a Verilog template named IBUFDS must be
- * integrated to use differential input:
- * {{{
- * IBUFDS #(.DIFF_TERM("TRUE"),
- * .IOSTANDARD("DEFAULT")) ibufds (
- * .IB(ibufds_IB),
- * .I(ibufds_I),
- * .O(ibufds_O)
- * );
- * }}}
- *
- * To instantiate it, a BlackBox can be used like following:
- * {{{
- * import chisel3._
- * import chisel3.experimental._
- *
- * // Example with Xilinx differential buffer IBUFDS
- * class IBUFDS extends BlackBox(Map("DIFF_TERM" -> "TRUE", // Verilog parameters
- * "IOSTANDARD" -> "DEFAULT"
- * )) {
- * val io = IO(new Bundle {
- * val O = Output(Clock()) // IO names will be the same
- * val I = Input(Clock()) // (without 'io_' in prefix)
- * val IB = Input(Clock()) //
- * })
- * }
- * }}}
- * @note The parameters API is experimental and may change
- */
-@nowarn("msg=class Port") // delete when Port becomes private
-abstract class BlackBox(
- val params: Map[String, Param] = Map.empty[String, Param]
-)(
- implicit compileOptions: CompileOptions)
- extends BaseBlackBox {
-
- // Find a Record port named "io" for purposes of stripping the prefix
- private[chisel3] lazy val _io: Option[Record] =
- this
- .findPort("io")
- .collect { case r: Record => r } // Must be a Record
-
- // Allow access to bindings from the compatibility package
- protected def _compatIoPortBound() = _io.exists(portsContains(_))
-
- private[chisel3] override def generateComponent(): Option[Component] = {
- _compatAutoWrapPorts() // pre-IO(...) compatibility hack
-
- // Restrict IO to just io, clock, and reset
- if (!_io.exists(portsContains)) {
- throwException(s"BlackBox '$this' must have a port named 'io' of type Record wrapped in IO(...)!")
- }
-
- require(portsSize == 1, "BlackBox must only have one IO, called `io`")
-
- require(!_closed, "Can't generate module more than once")
- _closed = true
-
- val io = _io.get
-
- val namedPorts = io.elements.toSeq.reverse // ListMaps are stored in reverse order
-
- // There is a risk of user improperly attempting to connect directly with io
- // Long term solution will be to define BlackBox IO differently as part of
- // it not descending from the (current) Module
- for ((name, port) <- namedPorts) {
- // We are setting a 'fake' ref for io, so that cloneType works but if a user connects to io, it still fails.
- this.findPort("io").get.setRef(ModuleIO(internal.ViewParent, ""), force = true)
- // We have to force override the _ref because it was set during IO binding
- port.setRef(ModuleIO(this, _namespace.name(name)), force = true)
- }
-
- // We need to call forceName and onModuleClose on all of the sub-elements
- // of the io bundle, but NOT on the io bundle itself.
- // Doing so would cause the wrong names to be assigned, since their parent
- // is now the module itself instead of the io bundle.
- for (id <- getIds; if id ne io) {
- id._onModuleClose
- }
-
- val firrtlPorts = namedPorts.map { namedPort => Port(namedPort._2, namedPort._2.specifiedDirection) }
- val component = DefBlackBox(this, name, firrtlPorts, io.specifiedDirection, params)
- _component = Some(component)
- _component
- }
-
- private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- if (!parentCompileOptions.explicitInvalidate) {
- for ((_, port) <- _io.map(_.elements).getOrElse(Nil)) {
- pushCommand(DefInvalid(UnlocatableSourceInfo, port.ref))
- }
- }
- }
-}
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala
index 259e6545..ec5a6321 100644
--- a/core/src/main/scala/chisel3/Data.scala
+++ b/core/src/main/scala/chisel3/Data.scala
@@ -2,10 +2,8 @@
package chisel3
-import chisel3.experimental.dataview.reify
-
import scala.language.experimental.macros
-import chisel3.experimental.{Analog, BaseModule, DataMirror, FixedPoint, Interval}
+import chisel3.experimental.{Analog, BaseModule, DataMirror}
import chisel3.internal.Builder.pushCommand
import chisel3.internal._
import chisel3.internal.firrtl._
@@ -146,8 +144,6 @@ object ActualDirection {
}
package experimental {
- import chisel3.internal.requireIsHardware // Fix ambiguous import
-
/** Experimental hardware construction reflection API
*/
object DataMirror {
@@ -222,7 +218,7 @@ package experimental {
* // )
* }}}
*/
- def modulePorts(target: BaseModule): Seq[(String, Data)] = target.getChiselPorts
+ def modulePorts(target: BaseModule): Seq[(String, Data)] = Seq.empty
/** Returns a recursive representation of a module's ports with underscore-qualified names
* {{{
@@ -318,24 +314,6 @@ private[chisel3] object cloneSupertype {
// TODO: perhaps redefine Widths to allow >= op?
if (elt1.width == (elt1.width.max(elt2.width))) elt1 else elt2
case (elt1: SInt, elt2: SInt) => if (elt1.width == (elt1.width.max(elt2.width))) elt1 else elt2
- case (elt1: FixedPoint, elt2: FixedPoint) => {
- (elt1.binaryPoint, elt2.binaryPoint, elt1.width, elt2.width) match {
- case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), KnownWidth(w1), KnownWidth(w2)) =>
- val maxBinaryPoint = bp1.max(bp2)
- val maxIntegerWidth = (w1 - bp1).max(w2 - bp2)
- FixedPoint((maxIntegerWidth + maxBinaryPoint).W, (maxBinaryPoint).BP)
- case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), _, _) =>
- FixedPoint(Width(), (bp1.max(bp2)).BP)
- case _ => FixedPoint()
- }
- }
- case (elt1: Interval, elt2: Interval) =>
- val range = if (elt1.range.width == elt1.range.width.max(elt2.range.width)) elt1.range else elt2.range
- Interval(range)
- case (elt1, elt2) =>
- throw new AssertionError(
- s"can't create $createdType with heterogeneous types ${elt1.getClass} and ${elt2.getClass}"
- )
}).asInstanceOf[T]
}
model.cloneTypeFull
@@ -629,7 +607,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
if (connectCompileOptions.emitStrictConnects) {
try {
- MonoConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.referenceUserModule)
+ MonoConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.currentModule.get)
} catch {
case MonoConnectException(message) =>
throwException(
@@ -658,7 +636,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
}
if (connectCompileOptions.emitStrictConnects) {
try {
- BiConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.referenceUserModule)
+ BiConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.currentModule.get)
} catch {
case BiConnectException(message) =>
throwException(
@@ -697,7 +675,6 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
topBindingOpt match {
case Some(binding: ReadOnlyBinding) =>
throwException(s"internal error: attempted to generate LHS ref to ReadOnlyBinding $binding")
- case Some(ViewBinding(target)) => reify(target).lref
case Some(binding: TopBinding) => Node(this)
case opt => throwException(s"internal error: unknown binding $opt in generating LHS ref")
}
@@ -713,14 +690,6 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
}
requireIsHardware(this)
topBindingOpt match {
- // DataView
- case Some(ViewBinding(target)) => reify(target).ref
- case Some(AggregateViewBinding(viewMap)) =>
- viewMap.get(this) match {
- case None => materializeWire() // FIXME FIRRTL doesn't have Aggregate Init expressions
- // This should not be possible because Element does the lookup in .topBindingOpt
- case x: Some[_] => throwException(s"Internal Error: In .ref for $this got '$topBindingOpt' and '$x'")
- }
// Literals
case Some(ElementLitBinding(litArg)) => litArg
case Some(BundleLitBinding(litMap)) =>
@@ -928,8 +897,6 @@ object Data {
case (thiz: SInt, that: SInt) => thiz === that
case (thiz: AsyncReset, that: AsyncReset) => thiz.asBool === that.asBool
case (thiz: Reset, that: Reset) => thiz === that
- case (thiz: Interval, that: Interval) => thiz === that
- case (thiz: FixedPoint, that: FixedPoint) => thiz === that
case (thiz: EnumType, that: EnumType) => thiz === that
case (thiz: Clock, that: Clock) => thiz.asUInt === that.asUInt
case (thiz: Vec[_], that: Vec[_]) =>
@@ -992,7 +959,7 @@ trait WireFactory {
x.bind(WireBinding(Builder.forcedUserModule, Builder.currentWhen))
pushCommand(DefWire(sourceInfo, x))
- if (!compileOptions.explicitInvalidate || Builder.currentModule.get.isInstanceOf[ImplicitInvalidate]) {
+ if (!compileOptions.explicitInvalidate) {
pushCommand(DefInvalid(sourceInfo, x.ref))
}
diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala
index a2d5cec6..794d1bf4 100644
--- a/core/src/main/scala/chisel3/Module.scala
+++ b/core/src/main/scala/chisel3/Module.scala
@@ -172,7 +172,7 @@ abstract class Module(implicit moduleCompileOptions: CompileOptions) extends Raw
private[chisel3] def mkReset: Reset = {
// Top module and compatibility mode use Bool for reset
// Note that a Definition elaboration will lack a parent, but still not be a Top module
- val inferReset = (_parent.isDefined || Builder.inDefinition) && moduleCompileOptions.inferModuleReset
+ val inferReset = (_parent.isDefined) && moduleCompileOptions.inferModuleReset
if (moduleCompileOptions.migrateInferModuleReset && !moduleCompileOptions.inferModuleReset) {
this match {
case _: RequireSyncReset => // Good! It's been migrated.
@@ -210,215 +210,16 @@ package experimental {
package internal {
import chisel3.experimental.BaseModule
- import chisel3.experimental.hierarchy.{Clone, IsInstantiable, Proto}
- object BaseModule {
-
- /** Represents a clone of an underlying object. This is used to support CloneModuleAsRecord and Instance/Definition.
- *
- * @note We don't actually "clone" anything in the traditional sense but is a placeholder so we lazily clone internal state
- */
- trait IsClone[+T] {
- // Underlying object of which this is a clone of
- private[chisel3] def getProto: T
-
- /** Determines whether another object is a clone of the same underlying proto
- *
- * @param a
- */
- def hasSameProto(a: Any): Boolean = {
- val aProto = a match {
- case x: IsClone[BaseModule] => x.getProto
- case o => o
- }
- this == aProto || getProto == aProto
- }
- }
-
- // Private internal class to serve as a _parent for Data in cloned ports
- private[chisel3] class ModuleClone[T <: BaseModule](val getProto: T) extends PseudoModule with IsClone[T] {
- override def toString = s"ModuleClone(${getProto})"
- // Do not call default addId function, which may modify a module that is already "closed"
- override def addId(d: HasId): Unit = ()
- def getPorts = _portsRecord
- // ClonePorts that hold the bound ports for this module
- // Used for setting the refs of both this module and the Record
- private[BaseModule] var _portsRecord: Record = _
- // This is necessary for correctly supporting .toTarget on a Module Clone. If it is made from the
- // Instance/Definition API, it should return an instanceTarget. If made from CMAR, it should return a
- // ModuleTarget.
- private[chisel3] var _madeFromDefinition: Boolean = false
- // Don't generate a component, but point to the one for the cloned Module
- private[chisel3] def generateComponent(): Option[Component] = {
- require(!_closed, "Can't generate module more than once")
- _closed = true
- _component = getProto._component
- None
- }
- // Maps proto ports to module clone's ports
- private[chisel3] lazy val ioMap: Map[Data, Data] = {
- getProto match {
- // BlackBox needs special handling for its pseduo-io Bundle
- case protoBB: BlackBox =>
- Map(protoBB._io.get -> getPorts.elements("io"))
- case _ =>
- val name2Port = getPorts.elements
- getProto.getChiselPorts.map { case (name, data) => data -> name2Port(name) }.toMap
- }
- }
- // This module doesn't actually exist in the FIRRTL so no initialization to do
- private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = ()
-
- // Name of this instance's module is the same as the proto's name
- override def desiredName: String = getProto.name
-
- private[chisel3] def setRefAndPortsRef(namespace: Namespace): Unit = {
- val record = _portsRecord
- // Use .forceName to re-use default name resolving behavior
- record.forceName(default = this.desiredName, namespace)
- // Now take the Ref that forceName set and convert it to the correct Arg
- val instName = record.getRef match {
- case Ref(name) => name
- case bad => throwException(s"Internal Error! Cloned-module Record $record has unexpected ref $bad")
- }
- // Set both the record and the module to have the same instance name
- val ref = ModuleCloneIO(getProto, instName)
- record.setRef(ref, force = true) // force because we did .forceName first
- getProto match {
- // BlackBox needs special handling for its pseduo-io Bundle
- case _: BlackBox =>
- // Override the io Bundle's ref so that it thinks it is the top for purposes of
- // generating FIRRTL
- record.elements("io").setRef(ref, force = true)
- case _ => // Do nothing
- }
-
- this.setRef(Ref(instName))
- }
- }
-
- /** Represents a module viewed from a different instance context.
- *
- * @note Why do we need both ModuleClone and InstanceClone? If we are annotating a reference in a module-clone,
- * all submodules must be also be 'cloned' so the toTarget can be computed properly. However, we don't need separate
- * connectable ports for this instance; all that's different from the proto is the parent.
- *
- * @note In addition, the instance name of an InstanceClone is going to be the SAME as the proto, but this is not true
- * for ModuleClone.
- */
- private[chisel3] final class InstanceClone[T <: BaseModule](val getProto: T, val instName: () => String)
- extends PseudoModule
- with IsClone[T] {
- override def toString = s"InstanceClone(${getProto})"
- // No addition components are generated
- private[chisel3] def generateComponent(): Option[Component] = None
- // Necessary for toTarget to work
- private[chisel3] def setAsInstanceRef(): Unit = { this.setRef(Ref(instName())) }
- // This module doesn't acutally exist in the FIRRTL so no initialization to do
- private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = ()
- // Instance name is the same as proto's instance name
- override def instanceName = instName()
- // Module name is the same as proto's module name
- override def desiredName: String = getProto.name
- }
-
- /** Represents a Definition root module, when accessing something from a definition
- *
- * @note This is necessary to distinguish between the toTarget behavior for a Module returned from a Definition,
- * versus a normal Module. A normal Module.toTarget will always return a local target. If calling toTarget
- * on a Module returned from a Definition (and thus wrapped in an Instance), we need to return the non-local
- * target whose root is the Definition. This DefinitionClone is used to represent the root parent of the
- * InstanceClone (which represents the returned module).
- */
- private[chisel3] class DefinitionClone[T <: BaseModule](val getProto: T) extends PseudoModule with IsClone[T] {
- override def toString = s"DefinitionClone(${getProto})"
- // No addition components are generated
- private[chisel3] def generateComponent(): Option[Component] = None
- // Do not call default addId function, which may modify a module that is already "closed"
- override def addId(d: HasId): Unit = ()
- // Necessary for toTarget to work
- private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = ()
- // Module name is the same as proto's module name
- override def desiredName: String = getProto.name
- }
-
- /** @note If we are cloning a non-module, we need another object which has the proper _parent set!
- */
- trait InstantiableClone[T <: IsInstantiable] extends IsClone[T] {
- private[chisel3] def _innerContext: experimental.hierarchy.Hierarchy[_]
- private[chisel3] def getInnerContext: Option[BaseModule] = _innerContext.getInnerDataContext
- }
-
- /** Record type returned by CloneModuleAsRecord
- *
- * @note These are not true Data (the Record doesn't correspond to anything in the emitted
- * FIRRTL yet its elements *do*) so have some very specialized behavior.
- */
- private[chisel3] class ClonePorts(elts: (String, Data)*)(implicit compileOptions: CompileOptions) extends Record {
- val elements = ListMap(elts.map { case (name, d) => name -> d.cloneTypeFull }: _*)
- def apply(field: String) = elements(field)
- override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type]
- }
-
- private[chisel3] def cloneIORecord(
- proto: BaseModule
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): ClonePorts = {
- require(proto.isClosed, "Can't clone a module before module close")
- // Fake Module to serve as the _parent of the cloned ports
- // We make this before clonePorts because we want it to come up first in naming in
- // currentModule
- val cloneParent = Module(new ModuleClone(proto))
- require(proto.isClosed, "Can't clone a module before module close")
- require(cloneParent.getOptionRef.isEmpty, "Can't have ref set already!")
- // Fake Module to serve as the _parent of the cloned ports
- // We don't create this inside the ModuleClone because we need the ref to be set by the
- // currentModule (and not clonePorts)
- val clonePorts = proto match {
- // BlackBox needs special handling for its pseduo-io Bundle
- case b: BlackBox =>
- new ClonePorts(proto.getChiselPorts :+ ("io" -> b._io.get): _*)
- case _ => new ClonePorts(proto.getChiselPorts: _*)
- }
- // getChiselPorts (nor cloneTypeFull in general)
- // does not recursively copy the right specifiedDirection,
- // still need to fix it up here.
- Module.assignCompatDir(clonePorts)
- clonePorts.bind(PortBinding(cloneParent))
- clonePorts.setAllParents(Some(cloneParent))
- cloneParent._portsRecord = clonePorts
- // Normally handled during Module construction but ClonePorts really lives in its parent's parent
- if (!compileOptions.explicitInvalidate || Builder.currentModule.get.isInstanceOf[ImplicitInvalidate]) {
- // FIXME This almost certainly doesn't work since clonePorts is not a real thing...
- pushCommand(DefInvalid(sourceInfo, clonePorts.ref))
- }
- if (proto.isInstanceOf[Module]) {
- clonePorts("clock") := Module.clock
- clonePorts("reset") := Module.reset
- }
- clonePorts
- }
- }
+ object BaseModule {}
}
package experimental {
- import chisel3.experimental.hierarchy.{IsInstantiable, Proto}
-
- object BaseModule {
- implicit class BaseModuleExtensions[T <: BaseModule](b: T) {
- import chisel3.experimental.hierarchy.{Definition, Instance}
- def toInstance: Instance[T] = new Instance(Proto(b))
- def toDefinition: Definition[T] = new Definition(Proto(b))
- }
- }
-
/** Abstract base class for Modules, an instantiable organizational unit for RTL.
*/
// TODO: seal this?
- abstract class BaseModule extends HasId with IsInstantiable {
+ abstract class BaseModule extends HasId {
_parent.foreach(_.addId(this))
//
@@ -450,12 +251,8 @@ package experimental {
private[chisel3] val _namespace = Namespace.empty
private val _ids = ArrayBuffer[HasId]()
private[chisel3] def addId(d: HasId) {
- if (Builder.aspectModule(this).isDefined) {
- aspectModule(this).get.addId(d)
- } else {
- require(!_closed, "Can't write to module after module close")
- _ids += d
- }
+ require(!_closed, "Can't write to module after module close")
+ _ids += d
}
// Returns the last id contained within a Module
@@ -471,25 +268,6 @@ package experimental {
_ids.toSeq
}
- private val _ports = new ArrayBuffer[Data]()
-
- // getPorts unfortunately already used for tester compatibility
- protected[chisel3] def getModulePorts = {
- require(_closed, "Can't get ports before module close")
- _ports.toSeq
- }
-
- // These methods allow checking some properties of ports before the module is closed,
- // mainly for compatibility purposes.
- protected def portsContains(elem: Data): Boolean = _ports contains elem
-
- // This is dangerous because it can be called before the module is closed and thus there could
- // be more ports and names have not yet been finalized.
- // This should only to be used during the process of closing when it is safe to do so.
- private[chisel3] def findPort(name: String): Option[Data] = _ports.find(_.seedOpt.contains(name))
-
- protected def portsSize: Int = _ports.size
-
/** Generates the FIRRTL Component (Module or Blackbox) of this Module.
* Also closes the module so no more construction can happen inside.
*/
@@ -499,27 +277,6 @@ package experimental {
*/
private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit
- private[chisel3] def namePorts(names: HashMap[HasId, String]): Unit = {
- for (port <- getModulePorts) {
- port._computeName(None).orElse(names.get(port)) match {
- case Some(name) =>
- if (_namespace.contains(name)) {
- Builder.error(
- s"""Unable to name port $port to "$name" in $this,""" +
- " name is already taken by another port!"
- )
- }
- port.setRef(ModuleIO(this, _namespace.name(name)))
- case None =>
- Builder.error(
- s"Unable to name port $port in $this, " +
- "try making it a public field of the Module"
- )
- port.setRef(ModuleIO(this, "<UNNAMED>"))
- }
- }
- }
-
//
// Chisel Internals
//
@@ -578,35 +335,9 @@ package experimental {
*
* @note Should not be called until circuit elaboration is complete
*/
- final def toTarget: ModuleTarget = this match {
- case m: internal.BaseModule.InstanceClone[_] =>
- throwException(s"Internal Error! It's not legal to call .toTarget on an InstanceClone. $m")
- case m: internal.BaseModule.DefinitionClone[_] =>
- throwException(s"Internal Error! It's not legal to call .toTarget on an DefinitionClone. $m")
- case _ => ModuleTarget(this.circuitName, this.name)
- }
+ final def toTarget: ModuleTarget = ModuleTarget(this.circuitName, this.name)
- /** Returns the real target of a Module which may be an [[InstanceTarget]]
- *
- * BaseModule.toTarget returns a ModuleTarget because the classic Module(new MyModule) API elaborates
- * Modules in a way that there is a 1:1 relationship between instances and elaborated definitions
- *
- * Instance/Definition introduced special internal modules [[InstanceClone]] and [[ModuleClone]] that
- * do not have this 1:1 relationship so need the ability to return [[InstanceTarget]]s.
- * Because users can never actually get references to these underlying objects, we can maintain
- * BaseModule.toTarget's API returning [[ModuleTarget]] while providing an internal API for getting
- * the correct [[InstanceTarget]]s whenever using the Definition/Instance API.
- */
- private[chisel3] def getTarget: IsModule = this match {
- case m: internal.BaseModule.InstanceClone[_] if m._parent.nonEmpty =>
- m._parent.get.getTarget.instOf(instanceName, name)
- case m: internal.BaseModule.ModuleClone[_] if m._madeFromDefinition =>
- m._parent.get.getTarget.instOf(instanceName, name)
- // Without this, we get the wrong CircuitName for the Definition
- case m: internal.BaseModule.DefinitionClone[_] if m._circuit.nonEmpty =>
- ModuleTarget(this._circuit.get.circuitName, this.name)
- case _ => this.toTarget
- }
+ private[chisel3] def getTarget: IsModule = this.toTarget
/** Returns a FIRRTL ModuleTarget that references this object
*
@@ -615,30 +346,7 @@ package experimental {
final def toAbsoluteTarget: IsModule = {
_parent match {
case Some(parent) => parent.toAbsoluteTarget.instOf(this.instanceName, name)
- case None =>
- // FIXME Special handling for Views - evidence of "weirdness" of .toAbsoluteTarget
- // In theory, .toAbsoluteTarget should not be necessary, .toTarget combined with the
- // target disambiguation in FIRRTL's deduplication transform should ensure that .toTarget
- // is always unambigous. However, legacy workarounds for Chisel's lack of an instance API
- // have lead some to use .toAbsoluteTarget as a workaround. A proper instance API will make
- // it possible to deprecate and remove .toAbsoluteTarget
- if (this == ViewParent) ViewParent.absoluteTarget else getTarget
- }
- }
-
- /**
- * Internal API. Returns a list of this module's generated top-level ports as a map of a String
- * (FIRRTL name) to the IO object. Only valid after the module is closed.
- *
- * Note: for BlackBoxes (but not ExtModules), this returns the contents of the top-level io
- * object, consistent with what is emitted in FIRRTL.
- *
- * TODO: Use SeqMap/VectorMap when those data structures become available.
- */
- private[chisel3] def getChiselPorts: Seq[(String, Data)] = {
- require(_closed, "Can't get ports before module close")
- _component.get.ports.map { port =>
- (port.id.getRef.asInstanceOf[ModuleIO].name, port.id)
+ case None => getTarget
}
}
@@ -699,7 +407,6 @@ package experimental {
Module.assignCompatDir(iodef)
iodef.bind(PortBinding(this))
- _ports += iodef
}
/** Private accessor for _bindIoInPlace */
diff --git a/core/src/main/scala/chisel3/ModuleAspect.scala b/core/src/main/scala/chisel3/ModuleAspect.scala
deleted file mode 100644
index 471ab980..00000000
--- a/core/src/main/scala/chisel3/ModuleAspect.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3
-
-import chisel3.internal.{Builder, PseudoModule}
-
-/** Used by Chisel Aspects to inject Chisel code into modules, after they have been elaborated.
- * This is an internal API - don't use!
- *
- * It adds itself as an aspect to the module, which allows proper checking of connection and binding legality.
- *
- * @param module Module for which this object is an aspect of
- * @param moduleCompileOptions
- */
-abstract class ModuleAspect private[chisel3] (module: RawModule)(implicit moduleCompileOptions: CompileOptions)
- extends RawModule
- with PseudoModule {
-
- Builder.addAspect(module, this)
-
- override def circuitName: String = module.toTarget.circuit
-
- override def desiredName: String = module.name
-
- override val _namespace = module._namespace
-}
diff --git a/core/src/main/scala/chisel3/Num.scala b/core/src/main/scala/chisel3/Num.scala
index c7e0721f..4a984b5a 100644
--- a/core/src/main/scala/chisel3/Num.scala
+++ b/core/src/main/scala/chisel3/Num.scala
@@ -2,7 +2,6 @@
package chisel3
-import chisel3.internal.ChiselException
import chisel3.internal.firrtl.{BinaryPoint, KnownBinaryPoint}
import scala.language.experimental.macros
diff --git a/core/src/main/scala/chisel3/RawModule.scala b/core/src/main/scala/chisel3/RawModule.scala
index 9668313a..19b719e0 100644
--- a/core/src/main/scala/chisel3/RawModule.scala
+++ b/core/src/main/scala/chisel3/RawModule.scala
@@ -7,7 +7,6 @@ import scala.language.experimental.macros
import scala.annotation.nowarn
import chisel3.experimental.BaseModule
import chisel3.internal._
-import chisel3.internal.BaseModule.{InstanceClone, ModuleClone}
import chisel3.internal.Builder._
import chisel3.internal.firrtl._
import chisel3.internal.sourceinfo.UnlocatableSourceInfo
@@ -37,14 +36,6 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends
_component.get.asInstanceOf[DefModule].commands
}
- //
- // Other Internal Functions
- //
- private var _firrtlPorts: Option[Seq[firrtl.Port]] = None
-
- @deprecated("Use DataMirror.modulePorts instead. this API will be removed in Chisel 3.6", "Chisel 3.5")
- lazy val getPorts: Seq[Port] = _firrtlPorts.get
-
val compileOptions = moduleCompileOptions
// This could be factored into a common utility
@@ -69,9 +60,6 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends
val names = nameIds(classOf[RawModule])
- // Ports get first naming priority, since they are part of a Module's IO spec
- namePorts(names)
-
// Then everything else gets named
val warnReflectiveNaming = Builder.warnReflectiveNaming
for ((node, name) <- names) {
@@ -96,8 +84,6 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends
// All suggestions are in, force names to every node.
for (id <- getIds) {
id match {
- case id: ModuleClone[_] => id.setRefAndPortsRef(_namespace) // special handling
- case id: InstanceClone[_] => id.setAsInstanceRef()
case id: BaseModule => id.forceName(default = id.desiredName, _namespace)
case id: MemBase[_] => id.forceName(default = "MEM", _namespace)
case id: stop.Stop => id.forceName(default = "stop", _namespace)
@@ -127,50 +113,12 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends
closeUnboundIds(names)
- val firrtlPorts = getModulePorts.map { port: Data =>
- // Special case Vec to make FIRRTL emit the direction of its
- // element.
- // Just taking the Vec's specifiedDirection is a bug in cases like
- // Vec(Flipped()), since the Vec's specifiedDirection is
- // Unspecified.
- val direction = port match {
- case v: Vec[_] =>
- v.specifiedDirection match {
- case SpecifiedDirection.Input => SpecifiedDirection.Input
- case SpecifiedDirection.Output => SpecifiedDirection.Output
- case SpecifiedDirection.Flip => SpecifiedDirection.flip(v.sample_element.specifiedDirection)
- case SpecifiedDirection.Unspecified => v.sample_element.specifiedDirection
- }
- case _ => port.specifiedDirection
- }
-
- Port(port, direction)
- }
- _firrtlPorts = Some(firrtlPorts)
-
- // Generate IO invalidation commands to initialize outputs as unused,
- // unless the client wants explicit control over their generation.
- val invalidateCommands = {
- if (!compileOptions.explicitInvalidate || this.isInstanceOf[ImplicitInvalidate]) {
- getModulePorts.map { port => DefInvalid(UnlocatableSourceInfo, port.ref) }
- } else {
- Seq()
- }
- }
- val component = DefModule(this, name, firrtlPorts, invalidateCommands ++: _commands.result())
+ val component = DefModule(this, name, null, Seq.empty)
_component = Some(component)
_component
}
- private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
-
- if (!parentCompileOptions.explicitInvalidate || Builder.currentModule.get.isInstanceOf[ImplicitInvalidate]) {
- for (port <- getModulePorts) {
- pushCommand(DefInvalid(sourceInfo, port.ref))
- }
- }
- }
+ private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {}
}
trait RequireAsyncReset extends Module {
@@ -182,7 +130,6 @@ trait RequireSyncReset extends Module {
}
/** Mix with a [[RawModule]] to automatically connect DontCare to the module's ports, wires, and children instance IOs. */
-trait ImplicitInvalidate { self: RawModule => }
package object internal {
@@ -227,158 +174,4 @@ package object internal {
builder.toString
}
}
-
- // Private reflective version of "val io" to maintain Chisel.Module semantics without having
- // io as a virtual method. See https://github.com/freechipsproject/chisel3/pull/1550 for more
- // information about the removal of "val io"
- private def reflectivelyFindValIO(self: BaseModule): Option[Record] = {
- // Java reflection is faster and works for the common case
- def tryJavaReflect: Option[Record] = Try {
- self.getClass.getMethod("io").invoke(self).asInstanceOf[Record]
- }.toOption
- .filter(_ != null)
- // Anonymous subclasses don't work with Java reflection, so try slower, Scala reflection
- def tryScalaReflect: Option[Record] = {
- val ru = scala.reflect.runtime.universe
- import ru.{Try => _, _}
- val m = ru.runtimeMirror(self.getClass.getClassLoader)
- val im = m.reflect(self)
- val tpe = im.symbol.toType
- // For some reason, in anonymous subclasses, looking up the Term by name (TermName("io"))
- // hits an internal exception. Searching for the term seems to work though so we use that.
- val ioTerm: Option[TermSymbol] = tpe.decls.collectFirst {
- case d if d.name.toString == "io" && d.isTerm => d.asTerm
- }
- ioTerm.flatMap { term =>
- Try {
- im.reflectField(term).get.asInstanceOf[Record]
- }.toOption
- .filter(_ != null)
- }
- }
-
- tryJavaReflect
- .orElse(tryScalaReflect)
- .map(_.forceFinalName("io"))
- .orElse {
- // Fallback if reflection fails, user can wrap in IO(...)
- self.findPort("io").collect { case r: Record => r }
- }
- }
-
- /** Legacy Module class that restricts IOs to just io, clock, and reset, and provides a constructor
- * for threading through explicit clock and reset.
- *
- * '''Do not use this class in user code'''. Use whichever `Module` is imported by your wildcard
- * import (preferably `import chisel3._`).
- */
- abstract class LegacyModule(implicit moduleCompileOptions: CompileOptions) extends Module {
- // Provide a non-deprecated constructor
- def this(
- override_clock: Option[Clock] = None,
- override_reset: Option[Bool] = None
- )(
- implicit moduleCompileOptions: CompileOptions
- ) = {
- this()
- this.override_clock = override_clock
- this.override_reset = override_reset
- }
- def this(_clock: Clock)(implicit moduleCompileOptions: CompileOptions) =
- this(Option(_clock), None)(moduleCompileOptions)
- def this(_reset: Bool)(implicit moduleCompileOptions: CompileOptions) =
- this(None, Option(_reset))(moduleCompileOptions)
- def this(_clock: Clock, _reset: Bool)(implicit moduleCompileOptions: CompileOptions) =
- this(Option(_clock), Option(_reset))(moduleCompileOptions)
-
- // Sort of a DIY lazy val because if the user tries to construct hardware before val io is
- // constructed, _compatAutoWrapPorts will try to access it but it will be null
- // In that case, we basically need to delay setting this var until later
- private var _ioValue: Option[Record] = None
- private def _io: Option[Record] = _ioValue.orElse {
- _ioValue = reflectivelyFindValIO(this)
- _ioValue
- }
-
- // Allow access to bindings from the compatibility package
- protected def _compatIoPortBound() = _io.exists(portsContains(_))
-
- private[chisel3] override def generateComponent(): Option[Component] = {
- _compatAutoWrapPorts() // pre-IO(...) compatibility hack
-
- // Restrict IO to just io, clock, and reset
- if (_io.isEmpty || !_compatIoPortBound) {
- throwException(
- s"Compatibility mode Module '$this' must have a 'val io' Bundle. " +
- "If there is such a field and you still see this error, autowrapping has failed (sorry!). " +
- "Please wrap the Bundle declaration in IO(...)."
- )
- }
- require(
- (portsContains(clock)) && (portsContains(reset)),
- "Internal error, module did not have clock or reset as IO"
- )
- require(portsSize == 3, "Module must only have io, clock, and reset as IO")
-
- super.generateComponent()
- }
-
- override def _compatAutoWrapPorts(): Unit = {
- if (!_compatIoPortBound()) {
- _io.foreach(_bindIoInPlace(_))
- }
- }
- }
-
- import chisel3.experimental.Param
-
- /** Legacy BlackBox class will reflectively autowrap val io
- *
- * '''Do not use this class in user code'''. Use whichever `BlackBox` is imported by your wildcard
- * import (preferably `import chisel3._`).
- */
- abstract class LegacyBlackBox(
- params: Map[String, Param] = Map.empty[String, Param]
- )(
- implicit moduleCompileOptions: CompileOptions)
- extends chisel3.BlackBox(params) {
-
- override private[chisel3] lazy val _io: Option[Record] = reflectivelyFindValIO(this)
-
- // This class auto-wraps the BlackBox with IO(...), allowing legacy code (where IO(...) wasn't
- // required) to build.
- override def _compatAutoWrapPorts(): Unit = {
- if (!_compatIoPortBound()) {
- _io.foreach(_bindIoInPlace(_))
- }
- }
- }
-
- /** Internal API for [[ViewParent]] */
- sealed private[chisel3] class ViewParentAPI extends RawModule()(ExplicitCompileOptions.Strict) with PseudoModule {
- // We must provide `absoluteTarget` but not `toTarget` because otherwise they would be exactly
- // the same and we'd have no way to distinguish the kind of target when renaming view targets in
- // the Converter
- // Note that this is not overriding .toAbsoluteTarget, that is a final def in BaseModule that delegates
- // to this method
- private[chisel3] val absoluteTarget: IsModule = ModuleTarget(this.circuitName, "_$$AbsoluteView$$_")
-
- // This module is not instantiable
- override private[chisel3] def generateComponent(): Option[Component] = None
- override private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = ()
- // This module is not really part of the circuit
- _parent = None
-
- // Sigil to mark views, starts with '_' to make it a legal FIRRTL target
- override def desiredName = "_$$View$$_"
-
- private[chisel3] val fakeComponent: Component = DefModule(this, desiredName, Nil, Nil)
- }
-
- /** Special internal object representing the parent of all views
- *
- * @note this is a val instead of an object because of the need to wrap in Module(...)
- */
- private[chisel3] val ViewParent =
- Module.do_apply(new ViewParentAPI)(UnlocatableSourceInfo, ExplicitCompileOptions.Strict)
}
diff --git a/core/src/main/scala/chisel3/SIntFactory.scala b/core/src/main/scala/chisel3/SIntFactory.scala
index 3fafacda..8cceda13 100644
--- a/core/src/main/scala/chisel3/SIntFactory.scala
+++ b/core/src/main/scala/chisel3/SIntFactory.scala
@@ -2,7 +2,7 @@
package chisel3
-import chisel3.internal.firrtl.{IntervalRange, SLit, Width}
+import chisel3.internal.firrtl.{SLit, Width}
trait SIntFactory {
@@ -12,11 +12,6 @@ trait SIntFactory {
/** Create a SInt type or port with fixed width. */
def apply(width: Width): SInt = new SInt(width)
- /** Create a SInt with the specified range */
- def apply(range: IntervalRange): SInt = {
- apply(range.getWidth)
- }
-
/** Create an SInt literal with specified width. */
protected[chisel3] def Lit(value: BigInt, width: Width): SInt = {
val lit = SLit(value, width)
diff --git a/core/src/main/scala/chisel3/SeqUtils.scala b/core/src/main/scala/chisel3/SeqUtils.scala
index 9d975349..6cc7b6cf 100644
--- a/core/src/main/scala/chisel3/SeqUtils.scala
+++ b/core/src/main/scala/chisel3/SeqUtils.scala
@@ -2,7 +2,6 @@
package chisel3
-import chisel3.experimental.FixedPoint
import chisel3.internal.{prefix, throwException}
import scala.language.experimental.macros
@@ -73,9 +72,6 @@ private[chisel3] object SeqUtils {
/** Returns the data value corresponding to the lone true predicate.
* This is elaborated to firrtl using a structure that should be optimized into and and/or tree.
- *
- * @note assumes exactly one true predicate, results undefined otherwise
- * FixedPoint values or aggregates containing FixedPoint values cause this optimized structure to be lost
*/
def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg
@@ -108,26 +104,6 @@ private[chisel3] object SeqUtils {
val masked = for ((s, i) <- sInts) yield Mux(s, i, 0.S)
masked.reduceLeft(_ | _).asTypeOf(output)
- case _: FixedPoint =>
- val (sels, possibleOuts) = in.toSeq.unzip
-
- val (intWidths, binaryPoints) = in.toSeq.map {
- case (_, o) =>
- val fo = o.asInstanceOf[FixedPoint]
- require(fo.binaryPoint.known, "Mux1H requires width/binary points to be defined")
- (fo.getWidth - fo.binaryPoint.get, fo.binaryPoint.get)
- }.unzip
-
- if (intWidths.distinct.length == 1 && binaryPoints.distinct.length == 1) {
- buildAndOrMultiplexor(in)
- } else {
- val maxIntWidth = intWidths.max
- val maxBP = binaryPoints.max
- val inWidthMatched = Seq.fill(intWidths.length)(Wire(FixedPoint((maxIntWidth + maxBP).W, maxBP.BP)))
- inWidthMatched.zipWithIndex.foreach { case (e, idx) => e := possibleOuts(idx).asInstanceOf[FixedPoint] }
- buildAndOrMultiplexor(sels.zip(inWidthMatched))
- }
-
case agg: Aggregate =>
val allDefineWidth = in.forall { case (_, element) => element.widthOption.isDefined }
if (allDefineWidth) {
diff --git a/core/src/main/scala/chisel3/UIntFactory.scala b/core/src/main/scala/chisel3/UIntFactory.scala
index 64127991..66c6f9c8 100644
--- a/core/src/main/scala/chisel3/UIntFactory.scala
+++ b/core/src/main/scala/chisel3/UIntFactory.scala
@@ -2,7 +2,7 @@
package chisel3
-import chisel3.internal.firrtl.{IntervalRange, KnownWidth, ULit, UnknownWidth, Width}
+import chisel3.internal.firrtl.{KnownWidth, ULit, UnknownWidth, Width}
import firrtl.Utils
import firrtl.constraint.IsKnown
import firrtl.ir.{Closed, IntWidth, Open}
@@ -23,26 +23,4 @@ trait UIntFactory {
// Bind result to being an Literal
lit.bindLitArg(result)
}
-
- /** Create a UInt with the specified range, validate that range is effectively > 0
- */
- def apply(range: IntervalRange): UInt = {
- // Check is only done against lower bound because range will already insist that range high >= low
- range.lowerBound match {
- case Closed(bound) if bound < 0 =>
- throw new ChiselException(s"Attempt to create UInt with closed lower bound of $bound, must be > 0")
- case Open(bound) if bound < -1 =>
- throw new ChiselException(s"Attempt to create UInt with open lower bound of $bound, must be > -1")
- case _ =>
- }
-
- // because this is a UInt we don't have to take into account the lower bound
- val newWidth = if (range.upperBound.isInstanceOf[IsKnown]) {
- KnownWidth(Utils.getUIntWidth(range.maxAdjusted.get).max(1)) // max(1) handles range"[0,0]"
- } else {
- UnknownWidth()
- }
-
- apply(newWidth)
- }
}
diff --git a/core/src/main/scala/chisel3/aop/Aspect.scala b/core/src/main/scala/chisel3/aop/Aspect.scala
deleted file mode 100644
index dd014357..00000000
--- a/core/src/main/scala/chisel3/aop/Aspect.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3.RawModule
-import firrtl.annotations.{Annotation, NoTargetAnnotation}
-import firrtl.options.Unserializable
-import firrtl.AnnotationSeq
-
-/** Represents an aspect of a Chisel module, by specifying
- * what behavior should be done to instance, via the FIRRTL Annotation Mechanism
- * @tparam T Type of top-level module
- */
-abstract class Aspect[T <: RawModule] extends Annotation with Unserializable with NoTargetAnnotation {
-
- /** variable to save [[AnnotationSeq]] from [[chisel3.stage.phases.AspectPhase]]
- * to be used at [[chisel3.aop.injecting.InjectorAspect]], exposes annotations to [[chisel3.internal.DynamicContext]]
- */
- private[aop] var annotationsInAspect: AnnotationSeq = Seq()
-
- /** Convert this Aspect to a seq of FIRRTL annotation
- * @param top
- * @return
- */
- def toAnnotation(top: T): AnnotationSeq
-
- /** Called by [[chisel3.stage.phases.AspectPhase]] to resolve this Aspect into annotations
- * @param top
- * @return
- */
- private[chisel3] def resolveAspect(top: RawModule, remainingAnnotations: AnnotationSeq): AnnotationSeq = {
- annotationsInAspect = remainingAnnotations
- toAnnotation(top.asInstanceOf[T])
- }
-}
-
-/** Holds utility functions for Aspect stuff */
-object Aspect {
-
- /** Converts elaborated Chisel components to FIRRTL modules
- * @param chiselIR
- * @return
- */
- def getFirrtl(chiselIR: chisel3.internal.firrtl.Circuit): firrtl.ir.Circuit = {
- chisel3.internal.firrtl.Converter.convert(chiselIR)
- }
-}
diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala
index 7d89025c..7bb0ac5d 100644
--- a/core/src/main/scala/chisel3/experimental/Analog.scala
+++ b/core/src/main/scala/chisel3/experimental/Analog.scala
@@ -13,7 +13,6 @@ import chisel3.{
Element,
PString,
Printable,
- RawModule,
SpecifiedDirection,
UInt
}
@@ -50,7 +49,7 @@ final class Analog private (private[chisel3] val width: Width) extends Element {
// Used to enforce single bulk connect of Analog types, multi-attach is still okay
// Note that this really means 1 bulk connect per Module because a port can
// be connected in the parent module as well
- private[chisel3] val biConnectLocs = mutable.Map.empty[RawModule, SourceInfo]
+ private[chisel3] val biConnectLocs = mutable.Map.empty[BaseModule, SourceInfo]
// Define setter/getter pairing
// Analog can only be bound to Ports and Wires (and Unbound)
diff --git a/core/src/main/scala/chisel3/experimental/Attach.scala b/core/src/main/scala/chisel3/experimental/Attach.scala
index 5c9cfe53..1d32e941 100644
--- a/core/src/main/scala/chisel3/experimental/Attach.scala
+++ b/core/src/main/scala/chisel3/experimental/Attach.scala
@@ -15,7 +15,7 @@ object attach {
AttachException(": Conditional attach is not allowed!")
// Actual implementation
- private[chisel3] def impl(elts: Seq[Analog], contextModule: RawModule)(implicit sourceInfo: SourceInfo): Unit = {
+ private[chisel3] def impl(elts: Seq[Analog], contextModule: BaseModule)(implicit sourceInfo: SourceInfo): Unit = {
if (Builder.whenDepth != 0) throw ConditionalAttachException
// TODO Check that references are valid and can be attached
diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala b/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala
deleted file mode 100644
index c6ebe604..00000000
--- a/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala
+++ /dev/null
@@ -1,326 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.dataview
-
-import chisel3.experimental.BaseModule
-import chisel3.{getRecursiveFields, Data, Vec}
-
-import scala.annotation.implicitNotFound
-
-/** Typeclass interface for getting elements of type [[Data]]
- *
- * This is needed for validating [[DataView]]s targeting type `A`.
- * Can be thought of as "can be the Target of a DataView".
- *
- * Chisel provides some implementations in [[DataProduct$ object DataProduct]] that are available
- * by default in the implicit scope.
- *
- * @tparam A Type that has elements of type [[Data]]
- * @see [[https://www.chisel-lang.org/chisel3/docs/explanations/dataview#dataproduct Detailed Documentation]]
- */
-@implicitNotFound(
- "Could not find implicit value for DataProduct[${A}].\n" +
- "Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview#dataproduct"
-)
-trait DataProduct[-A] {
-
- /** Provides [[Data]] elements within some containing object
- *
- * @param a Containing object
- * @param path Hierarchical path to current signal (for error reporting)
- * @return Data elements and associated String paths (Strings for error reporting only!)
- */
- def dataIterator(a: A, path: String): Iterator[(Data, String)]
-
- /** Returns a checker to test if the containing object contains a `Data` object
- * @note Implementers may want to override if iterating on all `Data` is expensive for `A` and `A`
- * will primarily be used in `PartialDataViews`
- * @note The returned value is a function, not a true Set, but is describing the functionality of
- * Set containment
- * @param a Containing object
- * @return A checker that itself returns True if a given `Data` is contained in `a`
- * as determined by an `==` test
- */
- def dataSet(a: A): Data => Boolean = dataIterator(a, "").map(_._1).toSet
-}
-
-/** Low priority built-in implementations of [[DataProduct]]
- *
- * @note This trait exists so that `dataDataProduct` can be lower priority than `seqDataProduct` to resolve ambiguity
- */
-sealed trait LowPriorityDataProduct {
-
- /** [[DataProduct]] implementation for [[Data]] */
- implicit val dataDataProduct: DataProduct[Data] = new DataProduct[Data] {
- def dataIterator(a: Data, path: String): Iterator[(Data, String)] =
- getRecursiveFields.lazily(a, path).iterator
- }
-}
-
-/** Encapsulating object for built-in implementations of [[DataProduct]]
- *
- * @note DataProduct implementations provided in this object are available in the implicit scope
- */
-object DataProduct extends LowPriorityDataProduct {
-
- /** [[DataProduct]] implementation for [[BaseModule]] */
- implicit val userModuleDataProduct: DataProduct[BaseModule] = new DataProduct[BaseModule] {
- def dataIterator(a: BaseModule, path: String): Iterator[(Data, String)] = {
- a.getIds.iterator.flatMap {
- case d: Data if d.getOptionRef.isDefined => // Using ref to decide if it's truly hardware in the module
- Seq(d -> s"${path}.${d.instanceName}")
- case b: BaseModule => dataIterator(b, s"$path.${b.instanceName}")
- case _ => Seq.empty
- }
- }
- // Overridden for performance
- override def dataSet(a: BaseModule): Data => Boolean = {
- val lastId = a._lastId // Not cheap to compute
- // Return a function
- e => e._id > a._id && e._id <= lastId
- }
- }
-
- /** [[DataProduct]] implementation for any `Seq[A]` where `A` has an implementation of `DataProduct`. */
- implicit def seqDataProduct[A: DataProduct]: DataProduct[Seq[A]] = new DataProduct[Seq[A]] {
- def dataIterator(a: Seq[A], path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- a.iterator.zipWithIndex.flatMap {
- case (elt, idx) =>
- dpa.dataIterator(elt, s"$path[$idx]")
- }
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple2]] where each field has an implementation of `DataProduct`. */
- implicit def tuple2DataProduct[A: DataProduct, B: DataProduct]: DataProduct[(A, B)] = new DataProduct[(A, B)] {
- def dataIterator(tup: (A, B), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val (a, b) = tup
- dpa.dataIterator(a, s"$path._1") ++ dpb.dataIterator(b, s"$path._2")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple3]] where each field has an implementation of `DataProduct`. */
- implicit def tuple3DataProduct[A: DataProduct, B: DataProduct, C: DataProduct]: DataProduct[(A, B, C)] =
- new DataProduct[(A, B, C)] {
- def dataIterator(tup: (A, B, C), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val (a, b, c) = tup
- dpa.dataIterator(a, s"$path._1") ++ dpb.dataIterator(b, s"$path._2") ++ dpc.dataIterator(c, s"$path._3")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple4]] where each field has an implementation of `DataProduct`. */
- implicit def tuple4DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct
- ]: DataProduct[(A, B, C, D)] =
- new DataProduct[(A, B, C, D)] {
- def dataIterator(tup: (A, B, C, D), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val (a, b, c, d) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple5]] where each field has an implementation of `DataProduct`. */
- implicit def tuple5DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct,
- E: DataProduct
- ]: DataProduct[(A, B, C, D, E)] =
- new DataProduct[(A, B, C, D, E)] {
- def dataIterator(tup: (A, B, C, D, E), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val dpe = implicitly[DataProduct[E]]
- val (a, b, c, d, e) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4") ++
- dpe.dataIterator(e, s"$path._5")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple6]] where each field has an implementation of `DataProduct`. */
- implicit def tuple6DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct,
- E: DataProduct,
- F: DataProduct
- ]: DataProduct[(A, B, C, D, E, F)] =
- new DataProduct[(A, B, C, D, E, F)] {
- def dataIterator(tup: (A, B, C, D, E, F), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val dpe = implicitly[DataProduct[E]]
- val dpf = implicitly[DataProduct[F]]
- val (a, b, c, d, e, f) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4") ++
- dpe.dataIterator(e, s"$path._5") ++
- dpf.dataIterator(f, s"$path._6")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple7]] where each field has an implementation of `DataProduct`. */
- implicit def tuple7DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct,
- E: DataProduct,
- F: DataProduct,
- G: DataProduct
- ]: DataProduct[(A, B, C, D, E, F, G)] =
- new DataProduct[(A, B, C, D, E, F, G)] {
- def dataIterator(tup: (A, B, C, D, E, F, G), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val dpe = implicitly[DataProduct[E]]
- val dpf = implicitly[DataProduct[F]]
- val dpg = implicitly[DataProduct[G]]
- val (a, b, c, d, e, f, g) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4") ++
- dpe.dataIterator(e, s"$path._5") ++
- dpf.dataIterator(f, s"$path._6") ++
- dpg.dataIterator(g, s"$path._7")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple8]] where each field has an implementation of `DataProduct`. */
- implicit def tuple8DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct,
- E: DataProduct,
- F: DataProduct,
- G: DataProduct,
- H: DataProduct
- ]: DataProduct[(A, B, C, D, E, F, G, H)] =
- new DataProduct[(A, B, C, D, E, F, G, H)] {
- def dataIterator(tup: (A, B, C, D, E, F, G, H), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val dpe = implicitly[DataProduct[E]]
- val dpf = implicitly[DataProduct[F]]
- val dpg = implicitly[DataProduct[G]]
- val dph = implicitly[DataProduct[H]]
- val (a, b, c, d, e, f, g, h) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4") ++
- dpe.dataIterator(e, s"$path._5") ++
- dpf.dataIterator(f, s"$path._6") ++
- dpg.dataIterator(g, s"$path._7") ++
- dph.dataIterator(h, s"$path._8")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple9]] where each field has an implementation of `DataProduct`. */
- implicit def tuple9DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct,
- E: DataProduct,
- F: DataProduct,
- G: DataProduct,
- H: DataProduct,
- I: DataProduct
- ]: DataProduct[(A, B, C, D, E, F, G, H, I)] =
- new DataProduct[(A, B, C, D, E, F, G, H, I)] {
- def dataIterator(tup: (A, B, C, D, E, F, G, H, I), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val dpe = implicitly[DataProduct[E]]
- val dpf = implicitly[DataProduct[F]]
- val dpg = implicitly[DataProduct[G]]
- val dph = implicitly[DataProduct[H]]
- val dpi = implicitly[DataProduct[I]]
- val (a, b, c, d, e, f, g, h, i) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4") ++
- dpe.dataIterator(e, s"$path._5") ++
- dpf.dataIterator(f, s"$path._6") ++
- dpg.dataIterator(g, s"$path._7") ++
- dph.dataIterator(h, s"$path._8") ++
- dpi.dataIterator(i, s"$path._9")
- }
- }
-
- /** [[DataProduct]] implementation for any [[Tuple9]] where each field has an implementation of `DataProduct`. */
- implicit def tuple10DataProduct[
- A: DataProduct,
- B: DataProduct,
- C: DataProduct,
- D: DataProduct,
- E: DataProduct,
- F: DataProduct,
- G: DataProduct,
- H: DataProduct,
- I: DataProduct,
- J: DataProduct
- ]: DataProduct[(A, B, C, D, E, F, G, H, I, J)] =
- new DataProduct[(A, B, C, D, E, F, G, H, I, J)] {
- def dataIterator(tup: (A, B, C, D, E, F, G, H, I, J), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val dpc = implicitly[DataProduct[C]]
- val dpd = implicitly[DataProduct[D]]
- val dpe = implicitly[DataProduct[E]]
- val dpf = implicitly[DataProduct[F]]
- val dpg = implicitly[DataProduct[G]]
- val dph = implicitly[DataProduct[H]]
- val dpi = implicitly[DataProduct[I]]
- val dpj = implicitly[DataProduct[J]]
- val (a, b, c, d, e, f, g, h, i, j) = tup
- dpa.dataIterator(a, s"$path._1") ++
- dpb.dataIterator(b, s"$path._2") ++
- dpc.dataIterator(c, s"$path._3") ++
- dpd.dataIterator(d, s"$path._4") ++
- dpe.dataIterator(e, s"$path._5") ++
- dpf.dataIterator(f, s"$path._6") ++
- dpg.dataIterator(g, s"$path._7") ++
- dph.dataIterator(h, s"$path._8") ++
- dpi.dataIterator(i, s"$path._9") ++
- dpj.dataIterator(j, s"$path._10")
- }
- }
-}
diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala
deleted file mode 100644
index cc555b11..00000000
--- a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala
+++ /dev/null
@@ -1,618 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.dataview
-
-import chisel3._
-import chisel3.experimental.DataMirror.internal.chiselTypeClone
-import chisel3.experimental.{HWTuple10, HWTuple2, HWTuple3, HWTuple4, HWTuple5, HWTuple6, HWTuple7, HWTuple8, HWTuple9}
-import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo}
-import chisel3.ExplicitCompileOptions.Strict
-
-import scala.reflect.runtime.universe.WeakTypeTag
-import annotation.implicitNotFound
-
-/** Mapping between a target type `T` and a view type `V`
- *
- * Enables calling `.viewAs[T]` on instances of the target type.
- *
- * ==Detailed documentation==
- * - [[https://www.chisel-lang.org/chisel3/docs/explanations/dataview Explanation]]
- * - [[https://www.chisel-lang.org/chisel3/docs/cookbooks/dataview Cookbook]]
- *
- * @example {{{
- * class Foo(val w: Int) extends Bundle {
- * val a = UInt(w.W)
- * }
- * class Bar(val w: Int) extends Bundle {
- * val b = UInt(w.W)
- * }
- * // DataViews are created using factory methods in the companion object
- * implicit val view = DataView[Foo, Bar](
- * // The first argument is a function constructing a Foo from a Bar
- * foo => new Bar(foo.w)
- * // The remaining arguments are a variable number of field pairings
- * _.a -> _.b
- * )
- * }}}
- *
- * @tparam T Target type (must have an implementation of [[DataProduct]])
- * @tparam V View type
- * @see [[DataView$ object DataView]] for factory methods
- * @see [[PartialDataView object PartialDataView]] for defining non-total `DataViews`
- */
-@implicitNotFound(
- "Could not find implicit value for DataView[${T}, ${V}].\n" +
- "Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview"
-)
-sealed class DataView[T: DataProduct, V <: Data] private[chisel3] (
- /** Function constructing an object of the View type from an object of the Target type */
- private[chisel3] val mkView: T => V,
- /** Function that returns corresponding fields of the target and view */
- private[chisel3] val mapping: (T, V) => Iterable[(Data, Data)],
- // Aliasing this with a def below to make the ScalaDoc show up for the field
- _total: Boolean
-)(
- implicit private[chisel3] val sourceInfo: SourceInfo) {
-
- /** Indicates if the mapping contains every field of the target */
- def total: Boolean = _total
-
- override def toString: String = {
- val base = sourceInfo.makeMessage(x => x)
- val loc = if (base.nonEmpty) base else "@unknown"
- val name = if (total) "DataView" else "PartialDataView"
- s"$name(defined $loc)"
- }
-
- /** Compose two `DataViews` together to construct a view from the target of this `DataView` to the
- * view type of the second `DataView`
- *
- * @param g a DataView from `V` to new view-type `V2`
- * @tparam V2 View type of `DataView` `g`
- * @return a new `DataView` from the original `T` to new view-type `V2`
- */
- def andThen[V2 <: Data](g: DataView[V, V2])(implicit sourceInfo: SourceInfo): DataView[T, V2] = {
- val self = this
- // We have to pass the DataProducts and DataViews manually to .viewAs below
- val tdp = implicitly[DataProduct[T]]
- val vdp = implicitly[DataProduct[V]]
- new DataView[T, V2](
- t => g.mkView(mkView(t)),
- { case (t, v2) => List(t.viewAs[V](tdp, self).viewAs[V2](vdp, g) -> v2) },
- this.total && g.total
- ) {
- override def toString: String = s"$self andThen $g"
- }
- }
-}
-
-/** Factory methods for constructing [[DataView]]s, see class for example use */
-object DataView {
-
- /** Default factory method, alias for [[pairs]] */
- def apply[T: DataProduct, V <: Data](
- mkView: T => V,
- pairs: ((T, V) => (Data, Data))*
- )(
- implicit sourceInfo: SourceInfo
- ): DataView[T, V] =
- DataView.pairs(mkView, pairs: _*)
-
- /** Construct [[DataView]]s with pairs of functions from the target and view to corresponding fields */
- def pairs[T: DataProduct, V <: Data](
- mkView: T => V,
- pairs: ((T, V) => (Data, Data))*
- )(
- implicit sourceInfo: SourceInfo
- ): DataView[T, V] =
- mapping(mkView: T => V, swizzle(pairs))
-
- /** More general factory method for complex mappings */
- def mapping[T: DataProduct, V <: Data](
- mkView: T => V,
- mapping: (T, V) => Iterable[(Data, Data)]
- )(
- implicit sourceInfo: SourceInfo
- ): DataView[T, V] =
- new DataView[T, V](mkView, mapping, _total = true)
-
- /** Provides `invert` for invertible [[DataView]]s
- *
- * This must be done as an extension method because it applies an addition constraint on the `Target`
- * type parameter, namely that it must be a subtype of [[Data]].
- *
- * @note [[PartialDataView]]s are **not** invertible and will result in an elaboration time exception
- */
- implicit class InvertibleDataView[T <: Data: WeakTypeTag, V <: Data: WeakTypeTag](view: DataView[T, V]) {
- def invert(mkView: V => T): DataView[V, T] = {
- // It would've been nice to make this a compiler error, but it's unclear how to make that work.
- // We tried having separate TotalDataView and PartialDataView and only defining inversion for
- // TotalDataView. For some reason, implicit resolution wouldn't invert TotalDataViews. This is
- // probably because it was looking for the super-type DataView and since invertDataView was
- // only defined on TotalDataView, it wasn't included in implicit resolution. Thus we end up
- // with a runtime check.
- if (!view.total) {
- val tt = implicitly[WeakTypeTag[T]].tpe
- val vv = implicitly[WeakTypeTag[V]].tpe
- val msg = s"Cannot invert '$view' as it is non-total.\n Try providing a DataView[$vv, $tt]." +
- s"\n Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview."
- throw InvalidViewException(msg)
- }
- implicit val sourceInfo = view.sourceInfo
- new DataView[V, T](mkView, swapArgs(view.mapping), view.total)
- }
- }
-
- private[dataview] def swizzle[A, B, C, D](fs: Iterable[(A, B) => (C, D)]): (A, B) => Iterable[(C, D)] = {
- case (a, b) => fs.map(f => f(a, b))
- }
-
- private def swapArgs[A, B, C, D](f: (A, B) => Iterable[(C, D)]): (B, A) => Iterable[(D, C)] = {
- case (b, a) => f(a, b).map(_.swap)
- }
-
- // ****************************** Built-in Implementations of DataView ******************************
- // Sort of the "Standard library" implementations
-
- /** All Chisel Data are viewable as their own type */
- implicit def identityView[A <: Data](implicit sourceInfo: SourceInfo): DataView[A, A] =
- DataView[A, A](chiselTypeOf.apply, { case (x, y) => (x, y) })
-
- /** Provides `DataView[Seq[A], Vec[B]]` for all `A` such that there exists `DataView[A, B]` */
- implicit def seqDataView[A: DataProduct, B <: Data](
- implicit dv: DataView[A, B],
- sourceInfo: SourceInfo
- ): DataView[Seq[A], Vec[B]] = {
- // TODO this would need a better way to determine the prototype for the Vec
- DataView.mapping[Seq[A], Vec[B]](
- xs => Vec(xs.size, chiselTypeClone(xs.head.viewAs[B]))(sourceInfo, Strict), // xs.head is not correct in general
- { case (s, v) => s.zip(v).map { case (a, b) => a.viewAs[B] -> b } }
- )
- }
-
- /** Provides implementations of [[DataView]] for [[Tuple2]] to [[HWTuple2]] */
- implicit def tuple2DataView[T1: DataProduct, T2: DataProduct, V1 <: Data, V2 <: Data](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2), HWTuple2[V1, V2]] =
- DataView.mapping(
- { case (a, b) => new HWTuple2(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType) },
- {
- case ((a, b), hwt) =>
- Seq(a.viewAs[V1] -> hwt._1, b.viewAs[V2] -> hwt._2)
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple3]] to [[HWTuple3]] */
- implicit def tuple3DataView[T1: DataProduct, T2: DataProduct, T3: DataProduct, V1 <: Data, V2 <: Data, V3 <: Data](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3), HWTuple3[V1, V2, V3]] =
- DataView.mapping(
- { case (a, b, c) => new HWTuple3(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType) },
- {
- case ((a, b, c), hwt) =>
- Seq(a.viewAs[V1] -> hwt._1, b.viewAs[V2] -> hwt._2, c.viewAs[V3] -> hwt._3)
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple4]] to [[HWTuple4]] */
- implicit def tuple4DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4), HWTuple4[V1, V2, V3, V4]] =
- DataView.mapping(
- {
- case (a, b, c, d) =>
- new HWTuple4(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType)
- },
- {
- case ((a, b, c, d), hwt) =>
- Seq(a.viewAs[V1] -> hwt._1, b.viewAs[V2] -> hwt._2, c.viewAs[V3] -> hwt._3, d.viewAs[V4] -> hwt._4)
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple5]] to [[HWTuple5]] */
- implicit def tuple5DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4, T5), HWTuple5[V1, V2, V3, V4, V5]] = {
- DataView.mapping(
- {
- case tup: Tuple5[T1, T2, T3, T4, T5] =>
- val (a, b, c, d, e) = tup
- new HWTuple5(
- a.viewAs[V1].cloneType,
- b.viewAs[V2].cloneType,
- c.viewAs[V3].cloneType,
- d.viewAs[V4].cloneType,
- e.viewAs[V5].cloneType
- )
- },
- {
- case ((a, b, c, d, e), hwt) =>
- Seq(
- a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2,
- c.viewAs[V3] -> hwt._3,
- d.viewAs[V4] -> hwt._4,
- e.viewAs[V5] -> hwt._5
- )
- }
- )
- }
-
- /** Provides implementations of [[DataView]] for [[Tuple6]] to [[HWTuple6]] */
- implicit def tuple6DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- T6: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data,
- V6 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5],
- v6: DataView[T6, V6],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4, T5, T6), HWTuple6[V1, V2, V3, V4, V5, V6]] =
- DataView.mapping(
- {
- case (a, b, c, d, e, f) =>
- new HWTuple6(
- a.viewAs[V1].cloneType,
- b.viewAs[V2].cloneType,
- c.viewAs[V3].cloneType,
- d.viewAs[V4].cloneType,
- e.viewAs[V5].cloneType,
- f.viewAs[V6].cloneType
- )
- },
- {
- case ((a, b, c, d, e, f), hwt) =>
- Seq(
- a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2,
- c.viewAs[V3] -> hwt._3,
- d.viewAs[V4] -> hwt._4,
- e.viewAs[V5] -> hwt._5,
- f.viewAs[V6] -> hwt._6
- )
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple7]] to [[HWTuple7]] */
- implicit def tuple7DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- T6: DataProduct,
- T7: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data,
- V6 <: Data,
- V7 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5],
- v6: DataView[T6, V6],
- v7: DataView[T7, V7],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4, T5, T6, T7), HWTuple7[V1, V2, V3, V4, V5, V6, V7]] =
- DataView.mapping(
- {
- case (a, b, c, d, e, f, g) =>
- new HWTuple7(
- a.viewAs[V1].cloneType,
- b.viewAs[V2].cloneType,
- c.viewAs[V3].cloneType,
- d.viewAs[V4].cloneType,
- e.viewAs[V5].cloneType,
- f.viewAs[V6].cloneType,
- g.viewAs[V7].cloneType
- )
- },
- {
- case ((a, b, c, d, e, f, g), hwt) =>
- Seq(
- a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2,
- c.viewAs[V3] -> hwt._3,
- d.viewAs[V4] -> hwt._4,
- e.viewAs[V5] -> hwt._5,
- f.viewAs[V6] -> hwt._6,
- g.viewAs[V7] -> hwt._7
- )
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple8]] to [[HWTuple8]] */
- implicit def tuple8DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- T6: DataProduct,
- T7: DataProduct,
- T8: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data,
- V6 <: Data,
- V7 <: Data,
- V8 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5],
- v6: DataView[T6, V6],
- v7: DataView[T7, V7],
- v8: DataView[T8, V8],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4, T5, T6, T7, T8), HWTuple8[V1, V2, V3, V4, V5, V6, V7, V8]] =
- DataView.mapping(
- {
- case (a, b, c, d, e, f, g, h) =>
- new HWTuple8(
- a.viewAs[V1].cloneType,
- b.viewAs[V2].cloneType,
- c.viewAs[V3].cloneType,
- d.viewAs[V4].cloneType,
- e.viewAs[V5].cloneType,
- f.viewAs[V6].cloneType,
- g.viewAs[V7].cloneType,
- h.viewAs[V8].cloneType
- )
- },
- {
- case ((a, b, c, d, e, f, g, h), hwt) =>
- Seq(
- a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2,
- c.viewAs[V3] -> hwt._3,
- d.viewAs[V4] -> hwt._4,
- e.viewAs[V5] -> hwt._5,
- f.viewAs[V6] -> hwt._6,
- g.viewAs[V7] -> hwt._7,
- h.viewAs[V8] -> hwt._8
- )
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple9]] to [[HWTuple9]] */
- implicit def tuple9DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- T6: DataProduct,
- T7: DataProduct,
- T8: DataProduct,
- T9: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data,
- V6 <: Data,
- V7 <: Data,
- V8 <: Data,
- V9 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5],
- v6: DataView[T6, V6],
- v7: DataView[T7, V7],
- v8: DataView[T8, V8],
- v9: DataView[T9, V9],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4, T5, T6, T7, T8, T9), HWTuple9[V1, V2, V3, V4, V5, V6, V7, V8, V9]] =
- DataView.mapping(
- {
- case (a, b, c, d, e, f, g, h, i) =>
- new HWTuple9(
- a.viewAs[V1].cloneType,
- b.viewAs[V2].cloneType,
- c.viewAs[V3].cloneType,
- d.viewAs[V4].cloneType,
- e.viewAs[V5].cloneType,
- f.viewAs[V6].cloneType,
- g.viewAs[V7].cloneType,
- h.viewAs[V8].cloneType,
- i.viewAs[V9].cloneType
- )
- },
- {
- case ((a, b, c, d, e, f, g, h, i), hwt) =>
- Seq(
- a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2,
- c.viewAs[V3] -> hwt._3,
- d.viewAs[V4] -> hwt._4,
- e.viewAs[V5] -> hwt._5,
- f.viewAs[V6] -> hwt._6,
- g.viewAs[V7] -> hwt._7,
- h.viewAs[V8] -> hwt._8,
- i.viewAs[V9] -> hwt._9
- )
- }
- )
-
- /** Provides implementations of [[DataView]] for [[Tuple10]] to [[HWTuple10]] */
- implicit def tuple10DataView[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- T6: DataProduct,
- T7: DataProduct,
- T8: DataProduct,
- T9: DataProduct,
- T10: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data,
- V6 <: Data,
- V7 <: Data,
- V8 <: Data,
- V9 <: Data,
- V10 <: Data
- ](
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5],
- v6: DataView[T6, V6],
- v7: DataView[T7, V7],
- v8: DataView[T8, V8],
- v9: DataView[T9, V9],
- v10: DataView[T10, V10],
- sourceInfo: SourceInfo
- ): DataView[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), HWTuple10[V1, V2, V3, V4, V5, V6, V7, V8, V9, V10]] =
- DataView.mapping(
- {
- case (a, b, c, d, e, f, g, h, i, j) =>
- new HWTuple10(
- a.viewAs[V1].cloneType,
- b.viewAs[V2].cloneType,
- c.viewAs[V3].cloneType,
- d.viewAs[V4].cloneType,
- e.viewAs[V5].cloneType,
- f.viewAs[V6].cloneType,
- g.viewAs[V7].cloneType,
- h.viewAs[V8].cloneType,
- i.viewAs[V9].cloneType,
- j.viewAs[V10].cloneType
- )
- },
- {
- case ((a, b, c, d, e, f, g, h, i, j), hwt) =>
- Seq(
- a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2,
- c.viewAs[V3] -> hwt._3,
- d.viewAs[V4] -> hwt._4,
- e.viewAs[V5] -> hwt._5,
- f.viewAs[V6] -> hwt._6,
- g.viewAs[V7] -> hwt._7,
- h.viewAs[V8] -> hwt._8,
- i.viewAs[V9] -> hwt._9,
- j.viewAs[V10] -> hwt._10
- )
- }
- )
-}
-
-/** Factory methods for constructing non-total [[DataView]]s */
-object PartialDataView {
-
- /** Default factory method, alias for [[pairs]] */
- def apply[T: DataProduct, V <: Data](
- mkView: T => V,
- pairs: ((T, V) => (Data, Data))*
- )(
- implicit sourceInfo: SourceInfo
- ): DataView[T, V] =
- PartialDataView.pairs(mkView, pairs: _*)
-
- /** Construct [[DataView]]s with pairs of functions from the target and view to corresponding fields */
- def pairs[T: DataProduct, V <: Data](
- mkView: T => V,
- pairs: ((T, V) => (Data, Data))*
- )(
- implicit sourceInfo: SourceInfo
- ): DataView[T, V] =
- mapping(mkView, DataView.swizzle(pairs))
-
- /** More general factory method for complex mappings */
- def mapping[T: DataProduct, V <: Data](
- mkView: T => V,
- mapping: (T, V) => Iterable[(Data, Data)]
- )(
- implicit sourceInfo: SourceInfo
- ): DataView[T, V] =
- new DataView[T, V](mkView, mapping, _total = false)
-
- /** Constructs a non-total [[DataView]] mapping from a [[Bundle]] type to a parent [[Bundle]] type
- *
- * @param mkView a function constructing an instance `V` from an instance of `T`
- * @return the [[DataView]] that enables viewing instances of a [[Bundle]] as instances of a parent type
- */
- def supertype[T <: Bundle, V <: Bundle](
- mkView: T => V
- )(
- implicit ev: SubTypeOf[T, V],
- sourceInfo: SourceInfo
- ): DataView[T, V] =
- mapping[T, V](
- mkView,
- {
- case (a, b) =>
- val aElts = a.elements
- val bElts = b.elements
- val bKeys = bElts.keySet
- val keys = aElts.keysIterator.filter(bKeys.contains)
- keys.map(k => aElts(k) -> bElts(k)).toSeq
- }
- )
-}
diff --git a/core/src/main/scala/chisel3/experimental/dataview/package.scala b/core/src/main/scala/chisel3/experimental/dataview/package.scala
deleted file mode 100644
index a52e88cf..00000000
--- a/core/src/main/scala/chisel3/experimental/dataview/package.scala
+++ /dev/null
@@ -1,268 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental
-
-import chisel3._
-import chisel3.internal._
-import chisel3.internal.sourceinfo.SourceInfo
-
-import scala.annotation.{implicitNotFound, tailrec}
-import scala.collection.mutable
-import scala.collection.immutable.LazyList // Needed for 2.12 alias
-
-package object dataview {
- case class InvalidViewException(message: String) extends ChiselException(message)
-
- /** Provides `viewAs` for types that have an implementation of [[DataProduct]]
- *
- * Calling `viewAs` also requires an implementation of [[DataView]] for the target type
- */
- implicit class DataViewable[T](target: T) {
- def viewAs[V <: Data](implicit dataproduct: DataProduct[T], dataView: DataView[T, V]): V = {
- // TODO put a try catch here for ExpectedHardwareException and perhaps others
- // It's likely users will accidentally use chiselTypeOf or something that may error,
- // The right thing to use is DataMirror...chiselTypeClone because of composition with DataView.andThen
- // Another option is that .andThen could give a fake binding making chiselTypeOfs in the user code safe
- val result: V = dataView.mkView(target)
- requireIsChiselType(result, "viewAs")
-
- doBind(target, result, dataView)
-
- // Setting the parent marks these Data as Views
- result.setAllParents(Some(ViewParent))
- // The names of views do not matter except for when a view is annotated. For Views that correspond
- // To a single Data, we just forward the name of the Target. For Views that correspond to more
- // than one Data, we return this assigned name but rename it in the Convert stage
- result.forceName("view", Builder.viewNamespace)
- result
- }
- }
-
- // This private type alias lets us provide a custom error message for misuing the .viewAs for upcasting Bundles
- @implicitNotFound(
- "${A} is not a subtype of ${B}! Did you mean .viewAs[${B}]? " +
- "Please see https://www.chisel-lang.org/chisel3/docs/cookbooks/dataview"
- )
- private[dataview] type SubTypeOf[A, B] = A <:< B
-
- /** Provides `viewAsSupertype` for subclasses of [[Bundle]] */
- implicit class BundleUpcastable[T <: Bundle](target: T) {
-
- /** View a [[Bundle]] or [[Record]] as a parent type (upcast) */
- def viewAsSupertype[V <: Bundle](proto: V)(implicit ev: SubTypeOf[T, V], sourceInfo: SourceInfo): V = {
- implicit val dataView = PartialDataView.supertype[T, V](_ => proto)
- target.viewAs[V]
- }
- }
-
- private def nonTotalViewException(
- dataView: DataView[_, _],
- target: Any,
- view: Data,
- targetFields: Seq[String],
- viewFields: Seq[String]
- ) = {
- def missingMsg(name: String, fields: Seq[String]): Option[String] = {
- val str = fields.mkString(", ")
- fields.size match {
- case 0 => None
- case 1 => Some(s"$name field '$str' is missing")
- case _ => Some(s"$name fields '$str' are missing")
- }
- }
- val vs = missingMsg("view", viewFields)
- val ts = missingMsg("target", targetFields)
- val reasons = (ts ++ vs).mkString(" and ").capitalize
- val suggestion = if (ts.nonEmpty) "\n If the view *should* be non-total, try a 'PartialDataView'." else ""
- val msg = s"Viewing $target as $view is non-Total!\n $reasons.\n DataView used is $dataView.$suggestion"
- throw InvalidViewException(msg)
- }
-
- // TODO should this be moved to class Aggregate / can it be unified with Aggregate.bind?
- private def doBind[T: DataProduct, V <: Data](target: T, view: V, dataView: DataView[T, V]): Unit = {
- val mapping = dataView.mapping(target, view)
- val total = dataView.total
- // Lookups to check the mapping results
- val viewFieldLookup: Map[Data, String] = getRecursiveFields(view, "_").toMap
- val targetContains: Data => Boolean = implicitly[DataProduct[T]].dataSet(target)
-
- // Resulting bindings for each Element of the View
- // Kept separate from Aggregates for totality checking
- val elementBindings =
- new mutable.HashMap[Data, mutable.ListBuffer[Element]] ++
- viewFieldLookup.view.collect { case (elt: Element, _) => elt }
- .map(_ -> new mutable.ListBuffer[Element])
-
- // Record any Aggregates that correspond 1:1 for reification
- // Using Data instead of Aggregate to avoid unnecessary checks
- val aggregateMappings = mutable.ArrayBuffer.empty[(Data, Data)]
-
- def viewFieldName(d: Data): String =
- viewFieldLookup.get(d).map(_ + " ").getOrElse("") + d.toString
-
- // Helper for recording the binding of each
- def onElt(te: Element, ve: Element): Unit = {
- // TODO can/should we aggregate these errors?
- def err(name: String, arg: Data) =
- throw InvalidViewException(s"View mapping must only contain Elements within the $name, got $arg")
-
- // The elements may themselves be views, look through the potential chain of views for the Elements
- // that are actually members of the target or view
- val tex = unfoldView(te).find(targetContains).getOrElse(err("Target", te))
- val vex = unfoldView(ve).find(viewFieldLookup.contains).getOrElse(err("View", ve))
-
- if (tex.getClass != vex.getClass) {
- val fieldName = viewFieldName(vex)
- throw InvalidViewException(s"Field $fieldName specified as view of non-type-equivalent value $tex")
- }
- // View width must be unknown or match target width
- if (vex.widthKnown && vex.width != tex.width) {
- def widthAsString(x: Element) = x.widthOption.map("<" + _ + ">").getOrElse("<unknown>")
- val fieldName = viewFieldName(vex)
- val vwidth = widthAsString(vex)
- val twidth = widthAsString(tex)
- throw InvalidViewException(
- s"View field $fieldName has width ${vwidth} that is incompatible with target value $tex's width ${twidth}"
- )
- }
- elementBindings(vex) += tex
- }
-
- mapping.foreach {
- // Special cased because getMatchedFields checks typeEquivalence on Elements (and is used in Aggregate path)
- // Also saves object allocations on common case of Elements
- case (ae: Element, be: Element) => onElt(ae, be)
-
- case (aa: Aggregate, ba: Aggregate) =>
- if (!ba.typeEquivalent(aa)) {
- val fieldName = viewFieldLookup(ba)
- throw InvalidViewException(s"field $fieldName specified as view of non-type-equivalent value $aa")
- }
- getMatchedFields(aa, ba).foreach {
- case (aelt: Element, belt: Element) => onElt(aelt, belt)
- case (t, v) => aggregateMappings += (v -> t)
- }
- }
-
- // Errors in totality of the View, use var List to keep fast path cheap (no allocation)
- var viewNonTotalErrors: List[Data] = Nil
- var targetNonTotalErrors: List[String] = Nil
-
- val targetSeen: Option[mutable.Set[Data]] = if (total) Some(mutable.Set.empty[Data]) else None
-
- val elementResult = elementBindings.map {
- case (data, targets) =>
- val targetsx = targets match {
- case collection.Seq(target: Element) => target
- case collection.Seq() =>
- viewNonTotalErrors = data :: viewNonTotalErrors
- data.asInstanceOf[Element] // Return the Data itself, will error after this map, cast is safe
- case x =>
- throw InvalidViewException(s"Got $x, expected Seq(_: Direct)")
- }
- // TODO record and report aliasing errors
- targetSeen.foreach(_ += targetsx)
- data -> targetsx
- }.toMap
-
- // Check for totality of Target
- targetSeen.foreach { seen =>
- val lookup = implicitly[DataProduct[T]].dataIterator(target, "_")
- for (missed <- lookup.collect { case (d: Element, name) if !seen(d) => name }) {
- targetNonTotalErrors = missed :: targetNonTotalErrors
- }
- }
- if (viewNonTotalErrors != Nil || targetNonTotalErrors != Nil) {
- val viewErrors = viewNonTotalErrors.map(f => viewFieldLookup.getOrElse(f, f.toString))
- nonTotalViewException(dataView, target, view, targetNonTotalErrors, viewErrors)
- }
-
- view match {
- case elt: Element => view.bind(ViewBinding(elementResult(elt)))
- case agg: Aggregate =>
- // Don't forget the potential mapping of the view to the target!
- target match {
- case d: Data if total =>
- aggregateMappings += (agg -> d)
- case _ =>
- }
-
- val fullResult = elementResult ++ aggregateMappings
-
- // We need to record any Aggregates that don't have a 1-1 mapping (including the view
- // itself)
- getRecursiveFields.lazily(view, "_").foreach {
- case (unnamed: Aggregate, _) if !fullResult.contains(unnamed) =>
- Builder.unnamedViews += unnamed
- case _ => // Do nothing
- }
- agg.bind(AggregateViewBinding(fullResult))
- }
- }
-
- // Traces an Element that may (or may not) be a view until it no longer maps
- // Inclusive of the argument
- private def unfoldView(elt: Element): LazyList[Element] = {
- def rec(e: Element): LazyList[Element] = e.topBindingOpt match {
- case Some(ViewBinding(target)) => target #:: rec(target)
- case Some(avb: AggregateViewBinding) =>
- val target = avb.lookup(e).get
- target #:: rec(target)
- case Some(_) | None => LazyList.empty
- }
- elt #:: rec(elt)
- }
-
- // Safe for all Data
- private[chisel3] def isView(d: Data): Boolean = d._parent.contains(ViewParent)
-
- /** Turn any [[Element]] that could be a View into a concrete Element
- *
- * This is the fundamental "unwrapping" or "tracing" primitive operation for handling Views within
- * Chisel.
- */
- private[chisel3] def reify(elt: Element): Element =
- reify(elt, elt.topBinding)
-
- /** Turn any [[Element]] that could be a View into a concrete Element
- *
- * This is the fundamental "unwrapping" or "tracing" primitive operation for handling Views within
- * Chisel.
- */
- @tailrec private[chisel3] def reify(elt: Element, topBinding: TopBinding): Element =
- topBinding match {
- case ViewBinding(target) => reify(target, elt.topBinding)
- case _ => elt
- }
-
- /** Determine the target of a View if it is a single Target
- *
- * @note An Aggregate may be a view of unrelated [[Data]] (eg. like a Seq or tuple) and thus this
- * there is no single Data representing the Target and this function will return None
- * @return The single Data target of this view or None if a single Data doesn't exist
- */
- private[chisel3] def reifySingleData(data: Data): Option[Data] = {
- val candidate: Option[Data] =
- data.topBindingOpt match {
- case None => None
- case Some(ViewBinding(target)) => Some(target)
- case Some(AggregateViewBinding(lookup)) => lookup.get(data)
- case Some(_) => None
- }
- candidate.flatMap { d =>
- // Candidate may itself be a view, keep tracing in those cases
- if (isView(d)) reifySingleData(d) else Some(d)
- }
- }
-
- /** Determine the target of a View if it is a single Target
- *
- * @note An Aggregate may be a view of unrelated [[Data]] (eg. like a Seq or tuple) and thus this
- * there is no single Data representing the Target and this function will return None
- * @return The single Data target of this view or None if a single Data doesn't exist
- */
- private[chisel3] def reifyToAggregate(data: Data): Option[Aggregate] = reifySingleData(data) match {
- case Some(a: Aggregate) => Some(a)
- case other => None
- }
-}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
deleted file mode 100644
index 99eacc7d..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
+++ /dev/null
@@ -1,126 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-import scala.language.experimental.macros
-import chisel3._
-
-import scala.collection.mutable.HashMap
-import chisel3.internal.{Builder, DynamicContext}
-import chisel3.internal.sourceinfo.{DefinitionTransform, DefinitionWrapTransform, SourceInfo}
-import chisel3.experimental.BaseModule
-import chisel3.internal.BaseModule.IsClone
-import firrtl.annotations.{IsModule, ModuleTarget}
-import firrtl.annotations.{IsModule, ModuleTarget, NoTargetAnnotation}
-
-/** User-facing Definition type.
- * Represents a definition of an object of type [[A]] which are marked as @instantiable
- * Can be created using Definition.apply method.
- *
- * These definitions are then used to create multiple [[Instance]]s.
- *
- * @param underlying The internal representation of the definition, which may be either be directly the object, or a clone of an object
- */
-final case class Definition[+A] private[chisel3] (private[chisel3] underlying: Underlying[A])
- extends IsLookupable
- with SealedHierarchy[A] {
-
- /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!!
- * Instead, mark the field you are accessing with [[@public]]
- *
- * Given a selector function (that) which selects a member from the original, return the
- * corresponding member from the instance.
- *
- * Our @instantiable and @public macros generate the calls to this apply method
- *
- * By calling this function, we summon the proper Lookupable typeclass from our implicit scope.
- *
- * @param that a user-specified lookup function
- * @param lookup typeclass which contains the correct lookup function, based on the types of A and B
- * @param macroGenerated a value created in the macro, to make it harder for users to use this API
- */
- def _lookup[B, C](
- that: A => B
- )(
- implicit lookup: Lookupable[B],
- macroGenerated: chisel3.internal.MacroGenerated
- ): lookup.C = {
- lookup.definitionLookup(that, this)
- }
-
- /** @return the context of any Data's return from inside the instance */
- private[chisel3] def getInnerDataContext: Option[BaseModule] = proto match {
- case value: BaseModule =>
- val newChild = Module.do_pseudo_apply(new internal.BaseModule.DefinitionClone(value))(
- chisel3.internal.sourceinfo.UnlocatableSourceInfo,
- chisel3.ExplicitCompileOptions.Strict
- )
- newChild._circuit = value._circuit.orElse(Some(value))
- newChild._parent = None
- Some(newChild)
- case value: IsInstantiable => None
- }
-
- override def toDefinition: Definition[A] = this
- override def toInstance: Instance[A] = new Instance(underlying)
-
-}
-
-/** Factory methods for constructing [[Definition]]s */
-object Definition extends SourceInfoDoc {
- implicit class DefinitionBaseModuleExtensions[T <: BaseModule](d: Definition[T]) {
-
- /** If this is an instance of a Module, returns the toTarget of this instance
- * @return target of this instance
- */
- def toTarget: ModuleTarget = d.proto.toTarget
-
- /** If this is an instance of a Module, returns the toAbsoluteTarget of this instance
- * @return absoluteTarget of this instance
- */
- def toAbsoluteTarget: IsModule = d.proto.toAbsoluteTarget
- }
-
- /** A construction method to build a Definition of a Module
- *
- * @param proto the Module being defined
- *
- * @return the input module as a Definition
- */
- def apply[T <: BaseModule with IsInstantiable](proto: => T): Definition[T] = macro DefinitionTransform.apply[T]
-
- /** A construction method to build a Definition of a Module
- *
- * @param bc the Module being defined
- *
- * @return the input module as a Definition
- */
- def do_apply[T <: BaseModule with IsInstantiable](
- proto: => T
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Definition[T] = {
- val dynamicContext = {
- val context = Builder.captureContext()
- new DynamicContext(Nil, context.throwOnFirstError, context.warnReflectiveNaming, context.warningsAsErrors)
- }
- Builder.globalNamespace.copyTo(dynamicContext.globalNamespace)
- dynamicContext.inDefinition = true
- val (ir, module) = Builder.build(Module(proto), dynamicContext, false)
- Builder.components ++= ir.components
- Builder.annotations ++= ir.annotations
- module._circuit = Builder.currentModule
- dynamicContext.globalNamespace.copyTo(Builder.globalNamespace)
- new Definition(Proto(module))
- }
-
-}
-
-/** Stores a [[Definition]] that is imported so that its Instances can be
- * compiled separately.
- */
-case class ImportDefinitionAnnotation[T <: BaseModule with IsInstantiable](
- definition: Definition[T],
- overrideDefName: Option[String] = None)
- extends NoTargetAnnotation
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
deleted file mode 100644
index 2016bb54..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
+++ /dev/null
@@ -1,117 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-import chisel3._
-import scala.collection.mutable.{HashMap, HashSet}
-import scala.reflect.runtime.universe.TypeTag
-import chisel3.internal.BaseModule.IsClone
-import chisel3.experimental.BaseModule
-import _root_.firrtl.annotations.IsModule
-import scala.annotation.implicitNotFound
-
-/** Super-trait for Instance and Definition
- *
- * Enables writing functions which are Instance/Definition agnostic
- */
-sealed trait Hierarchy[+A] {
- private[chisel3] def underlying: Underlying[A]
- private[chisel3] def proto: A = underlying match {
- case Proto(value: A) => value
- case Clone(i: IsClone[A]) => i.getProto
- }
-
- /** Updated by calls to [[_lookup]], to avoid recloning returned Data's */
- private[chisel3] val cache = HashMap[Data, Data]()
- private[chisel3] def getInnerDataContext: Option[BaseModule]
-
- /** Determine whether underlying proto is of type provided.
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[B], which will fail if B is an inner class.
- * @note IMPORTANT: this function IGNORES type parameters, akin to normal type erasure.
- * @note IMPORTANT: this function relies on Java reflection for underlying proto, but Scala reflection for provided type
- *
- * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String]
- * @return Whether underlying proto is of provided type (with caveats outlined above)
- */
- def isA[B: TypeTag]: Boolean = {
- val tptag = implicitly[TypeTag[B]]
- // drop any type information for the comparison, because the proto will not have that information.
- val name = tptag.tpe.toString.takeWhile(_ != '[')
- inBaseClasses(name)
- }
-
- // This code handles a special-case where, within an mdoc context, the type returned from
- // scala reflection (typetag) looks different than when returned from java reflection.
- // This function detects this case and reshapes the string to match.
- private def modifyReplString(clz: String): String = {
- if (clz != null) {
- clz.split('.').toList match {
- case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".")
- case other => clz
- }
- } else clz
- }
- private lazy val superClasses = calculateSuperClasses(proto.getClass())
- private def calculateSuperClasses(clz: Class[_]): Set[String] = {
- if (clz != null) {
- Set(modifyReplString(clz.getCanonicalName())) ++
- clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++
- calculateSuperClasses(clz.getSuperclass())
- } else {
- Set.empty[String]
- }
- }
- private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz)
-
- /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!!
- * Instead, mark the field you are accessing with [[@public]]
- *
- * Given a selector function (that) which selects a member from the original, return the
- * corresponding member from the hierarchy.
- *
- * Our @instantiable and @public macros generate the calls to this apply method
- *
- * By calling this function, we summon the proper Lookupable typeclass from our implicit scope.
- *
- * @param that a user-specified lookup function
- * @param lookup typeclass which contains the correct lookup function, based on the types of A and B
- * @param macroGenerated a value created in the macro, to make it harder for users to use this API
- */
- def _lookup[B, C](
- that: A => B
- )(
- implicit lookup: Lookupable[B],
- macroGenerated: chisel3.internal.MacroGenerated
- ): lookup.C
-
- /** @return Return the underlying Definition[A] of this Hierarchy[A] */
- def toDefinition: Definition[A]
-
- /** @return Convert this Hierarchy[A] as a top-level Instance[A] */
- def toInstance: Instance[A]
-}
-
-// Used to effectively seal Hierarchy, without requiring Definition and Instance to be in this file.
-private[chisel3] trait SealedHierarchy[+A] extends Hierarchy[A]
-
-object Hierarchy {
- implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) {
-
- /** Returns the toTarget of this hierarchy
- * @return target of this hierarchy
- */
- def toTarget: IsModule = i match {
- case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toTarget
- case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toTarget
- }
-
- /** Returns the toAbsoluteTarget of this hierarchy
- * @return absoluteTarget of this Hierarchy
- */
- def toAbsoluteTarget: IsModule = i match {
- case d: Definition[T] => new Definition.DefinitionBaseModuleExtensions(d).toAbsoluteTarget
- case i: Instance[T] => new Instance.InstanceBaseModuleExtensions(i).toAbsoluteTarget
- }
- }
-}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
deleted file mode 100644
index 861023a1..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
+++ /dev/null
@@ -1,148 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-import scala.language.experimental.macros
-import chisel3._
-import chisel3.internal.BaseModule.{InstantiableClone, IsClone, ModuleClone}
-import chisel3.internal.Builder
-import chisel3.internal.sourceinfo.{InstanceTransform, SourceInfo}
-import chisel3.experimental.{BaseModule, ExtModule}
-import chisel3.internal.firrtl.{Component, DefBlackBox, DefModule, Port}
-import firrtl.annotations.IsModule
-import chisel3.internal.throwException
-
-/** User-facing Instance type.
- * Represents a unique instance of type [[A]] which are marked as @instantiable
- * Can be created using Instance.apply method.
- *
- * @param underlying The internal representation of the instance, which may be either be directly the object, or a clone of an object
- */
-final case class Instance[+A] private[chisel3] (private[chisel3] underlying: Underlying[A]) extends SealedHierarchy[A] {
- underlying match {
- case Proto(p: IsClone[_]) => chisel3.internal.throwException("Cannot have a Proto with a clone!")
- case other => //Ok
- }
-
- /** @return the context of any Data's return from inside the instance */
- private[chisel3] def getInnerDataContext: Option[BaseModule] = underlying match {
- case Proto(value: BaseModule) => Some(value)
- case Proto(value: IsInstantiable) => None
- case Clone(i: BaseModule) => Some(i)
- case Clone(i: InstantiableClone[_]) => i.getInnerContext
- }
-
- /** @return the context this instance. Note that for non-module clones, getInnerDataContext will be the same as getClonedParent */
- private[chisel3] def getClonedParent: Option[BaseModule] = underlying match {
- case Proto(value: BaseModule) => value._parent
- case Clone(i: BaseModule) => i._parent
- case Clone(i: InstantiableClone[_]) => i.getInnerContext
- }
-
- /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!!
- * Instead, mark the field you are accessing with [[@public]]
- *
- * Given a selector function (that) which selects a member from the original, return the
- * corresponding member from the instance.
- *
- * Our @instantiable and @public macros generate the calls to this apply method
- *
- * By calling this function, we summon the proper Lookupable typeclass from our implicit scope.
- *
- * @param that a user-specified lookup function
- * @param lookup typeclass which contains the correct lookup function, based on the types of A and B
- * @param macroGenerated a value created in the macro, to make it harder for users to use this API
- */
- def _lookup[B, C](
- that: A => B
- )(
- implicit lookup: Lookupable[B],
- macroGenerated: chisel3.internal.MacroGenerated
- ): lookup.C = {
- lookup.instanceLookup(that, this)
- }
-
- /** Returns the definition of this Instance */
- override def toDefinition: Definition[A] = new Definition(Proto(proto))
- override def toInstance: Instance[A] = this
-
-}
-
-/** Factory methods for constructing [[Instance]]s */
-object Instance extends SourceInfoDoc {
- implicit class InstanceBaseModuleExtensions[T <: BaseModule](i: Instance[T]) {
-
- /** If this is an instance of a Module, returns the toTarget of this instance
- * @return target of this instance
- */
- def toTarget: IsModule = i.underlying match {
- case Proto(x: BaseModule) => x.getTarget
- case Clone(x: IsClone[_] with BaseModule) => x.getTarget
- }
-
- /** If this is an instance of a Module, returns the toAbsoluteTarget of this instance
- * @return absoluteTarget of this instance
- */
- def toAbsoluteTarget: IsModule = i.underlying match {
- case Proto(x) => x.toAbsoluteTarget
- case Clone(x: IsClone[_] with BaseModule) => x.toAbsoluteTarget
- }
-
- }
-
- /** A constructs an [[Instance]] from a [[Definition]]
- *
- * @param definition the Module being created
- * @return an instance of the module definition
- */
- def apply[T <: BaseModule with IsInstantiable](definition: Definition[T]): Instance[T] =
- macro InstanceTransform.apply[T]
-
- /** A constructs an [[Instance]] from a [[Definition]]
- *
- * @param definition the Module being created
- * @return an instance of the module definition
- */
- def do_apply[T <: BaseModule with IsInstantiable](
- definition: Definition[T]
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Instance[T] = {
- // Check to see if the module is already defined internally or externally
- val existingMod = Builder.components.map {
- case c: DefModule if c.id == definition.proto => Some(c)
- case c: DefBlackBox if c.name == definition.proto.name => Some(c)
- case _ => None
- }.flatten
-
- if (existingMod.isEmpty) {
- // Add a Definition that will get emitted as an ExtModule so that FIRRTL
- // does not complain about a missing element
- val extModName = Builder.importDefinitionMap.getOrElse(
- definition.proto.name,
- throwException(
- "Imported Definition information not found - possibly forgot to add ImportDefinition annotation?"
- )
- )
- class EmptyExtModule extends ExtModule {
- override def desiredName: String = extModName
- override def generateComponent(): Option[Component] = {
- require(!_closed, s"Can't generate $desiredName module more than once")
- _closed = true
- val firrtlPorts = definition.proto.getModulePorts.map { port => Port(port, port.specifiedDirection) }
- val component = DefBlackBox(this, definition.proto.name, firrtlPorts, SpecifiedDirection.Unspecified, params)
- Some(component)
- }
- }
- Definition(new EmptyExtModule() {})
- }
-
- val ports = experimental.CloneModuleAsRecord(definition.proto)
- val clone = ports._parent.get.asInstanceOf[ModuleClone[T]]
- clone._madeFromDefinition = true
-
- new Instance(Clone(clone))
- }
-
-}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala
deleted file mode 100644
index 27e06d92..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-/** While this is public, it is not recommended for users to extend directly.
- * Instead, use the [[@instantiable]] annotation on your trait or class.
- *
- * This trait indicates whether a class can be returned from an Instance.
- */
-trait IsInstantiable
-
-object IsInstantiable {
- implicit class IsInstantiableExtensions[T <: IsInstantiable](i: T) {
- def toInstance: Instance[T] = new Instance(Proto(i))
- }
-}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala
deleted file mode 100644
index a82cbd7d..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-/** A User-extendable trait to mark metadata-containers, e.g. parameter case classes, as valid to return unchanged
- * from an instance.
- *
- * This should only be true of the metadata returned is identical for ALL instances!
- *
- * @example For instances of the same proto, metadata or other construction parameters
- * may be useful to access outside of the instance construction. For parameters that are
- * the same for all instances, we should mark it as IsLookupable
- * {{{
- * case class Params(debugMessage: String) extends IsLookupable
- * class MyModule(p: Params) extends MultiIOModule {
- * printf(p.debugMessage)
- * }
- * val myParams = Params("Hello World")
- * val definition = Definition(new MyModule(myParams))
- * val i0 = Instance(definition)
- * val i1 = Instance(definition)
- * require(i0.p == i1.p) // p is only accessable because it extends IsLookupable
- * }}}
- */
-trait IsLookupable
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala b/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala
deleted file mode 100644
index d4818f63..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-import scala.annotation.implicitNotFound
-
-@implicitNotFound("These functions are only for building hierarchy-compatible Chisel libraries! Users beware!")
-// DO NOT extend unless you know what you are doing!!!!!! Not for the casual user!
-trait InsideHierarchyLibraryExtension
-
-// Collection of public functions to give non-core-Chisel libraries the ability to build integrations with
-// the experimental hierarchy package
-object LibraryHooks {
-
- /** Builds a new instance given a definition and function to create a new instance-specific Underlying, from the
- * definition's Underlying
- * @note Implicitly requires being inside a Hierarchy Library Extension
- */
- def buildInstance[A](
- definition: Definition[A],
- createUnderlying: Underlying[A] => Underlying[A]
- )(
- implicit inside: InsideHierarchyLibraryExtension
- ): Instance[A] = {
- new Instance(createUnderlying(definition.underlying))
- }
-
- /** Builds a new definition given an Underlying implementation
- * @note Implicitly requires being inside a Hierarchy Library Extension
- */
- def buildDefinition[A](underlying: Underlying[A])(implicit inside: InsideHierarchyLibraryExtension): Definition[A] = {
- new Definition(underlying)
- }
-}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
deleted file mode 100644
index aa35455d..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
+++ /dev/null
@@ -1,511 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-import chisel3.experimental.BaseModule
-import chisel3.internal.sourceinfo.SourceInfo
-import chisel3.internal.BaseModule.{InstanceClone, InstantiableClone, IsClone, ModuleClone}
-
-import scala.annotation.implicitNotFound
-import scala.collection.mutable.HashMap
-import chisel3._
-import chisel3.experimental.dataview.{isView, reify, reifySingleData}
-import chisel3.internal.firrtl.{Arg, ILit, Index, ModuleIO, Slot, ULit}
-import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBinding, ViewBinding, ViewParent}
-
-/** Represents lookup typeclass to determine how a value accessed from an original IsInstantiable
- * should be tweaked to return the Instance's version
- * Sealed.
- */
-@implicitNotFound(
- "@public is only legal within a class or trait marked @instantiable, and only on vals of type" +
- " Data, BaseModule, MemBase, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, Either, or Tuple2"
-)
-trait Lookupable[-B] {
- type C // Return type of the lookup
- /** Function called to modify the returned value of type B from A, into C
- *
- * @param that function that selects B from A
- * @param instance Instance of A, used to determine C's context
- * @return
- */
- def instanceLookup[A](that: A => B, instance: Instance[A]): C
-
- /** Function called to modify the returned value of type B from A, into C
- *
- * @param that function that selects B from A
- * @param definition Definition of A, used to determine C's context
- * @return
- */
- def definitionLookup[A](that: A => B, definition: Definition[A]): C
- protected def getProto[A](h: Hierarchy[A]): A = h.proto
- protected def getUnderlying[A](h: Hierarchy[A]): Underlying[A] = h.underlying
-}
-
-object Lookupable {
-
- /** Clones a data and sets its internal references to its parent module to be in a new context.
- *
- * @param data data to be cloned
- * @param context new context
- * @return
- */
- private[chisel3] def cloneDataToContext[T <: Data](
- data: T,
- context: BaseModule
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): T = {
- internal.requireIsHardware(data, "cross module reference type")
- data._parent match {
- case None => data
- case Some(parent) =>
- val newParent = cloneModuleToContext(Proto(parent), context)
- newParent match {
- case Proto(p) if p == parent => data
- case Clone(m: BaseModule) =>
- val newChild = data.cloneTypeFull
- newChild.setRef(data.getRef, true)
- newChild.bind(internal.CrossModuleBinding)
- newChild.setAllParents(Some(m))
- newChild
- }
- }
- }
- // The business logic of lookupData
- // Also called by cloneViewToContext which potentially needs to lookup stuff from ioMap or the cache
- private[chisel3] def doLookupData[A, B <: Data](
- data: B,
- cache: HashMap[Data, Data],
- ioMap: Option[Map[Data, Data]],
- context: Option[BaseModule]
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): B = {
- def impl[C <: Data](d: C): C = d match {
- case x: Data if ioMap.nonEmpty && ioMap.get.contains(x) => ioMap.get(x).asInstanceOf[C]
- case x: Data if cache.contains(x) => cache(x).asInstanceOf[C]
- case _ =>
- assert(context.nonEmpty) // TODO is this even possible? Better error message here
- val ret = cloneDataToContext(d, context.get)
- cache(d) = ret
- ret
- }
- data.binding match {
- case Some(_: ChildBinding) => mapRootAndExtractSubField(data, impl)
- case _ => impl(data)
- }
- }
-
- // Helper for co-iterating on Elements of aggregates, they must be the same type but that is unchecked
- private def coiterate(a: Data, b: Data): Iterable[(Element, Element)] = {
- val as = getRecursiveFields.lazily(a, "_")
- val bs = getRecursiveFields.lazily(b, "_")
- as.zip(bs).collect { case ((ae: Element, _), (be: Element, _)) => (ae, be) }
- }
-
- /** Given a Data, find the root of its binding, apply a function to the root to get a "new root",
- * and find the equivalent child Data in the "new root"
- *
- * @example {{{
- * Given `arg = a.b[2].c` and some `f`:
- * 1. a = root(arg) = root(a.b[2].c)
- * 2. newRoot = f(root(arg)) = f(a)
- * 3. return newRoot.b[2].c
- * }}}
- *
- * Invariants that elt is a Child of something of the type of data is dynamically checked as we traverse
- */
- private def mapRootAndExtractSubField[A <: Data](arg: A, f: Data => Data): A = {
- def err(msg: String) = throwException(s"Internal Error! $msg")
- def unrollCoordinates(res: List[Arg], d: Data): (List[Arg], Data) = d.binding.get match {
- case ChildBinding(parent) =>
- d.getRef match {
- case arg @ (_: Slot | _: Index | _: ModuleIO) => unrollCoordinates(arg :: res, parent)
- case other => err(s"unrollCoordinates failed for '$arg'! Unexpected arg '$other'")
- }
- case _ => (res, d)
- }
- def applyCoordinates(fullCoor: List[Arg], start: Data): Data = {
- def rec(coor: List[Arg], d: Data): Data = {
- if (coor.isEmpty) d
- else {
- val next = (coor.head, d) match {
- case (Slot(_, name), rec: Record) => rec.elements(name)
- case (Index(_, ILit(n)), vec: Vec[_]) => vec.apply(n.toInt)
- case (ModuleIO(_, name), rec: Record) => rec.elements(name)
- case (arg, _) => err(s"Unexpected Arg '$arg' applied to '$d'! Root was '$start'.")
- }
- applyCoordinates(coor.tail, next)
- }
- }
- rec(fullCoor, start)
- }
- val (coor, root) = unrollCoordinates(Nil, arg)
- val newRoot = f(root)
- val result = applyCoordinates(coor, newRoot)
- try {
- result.asInstanceOf[A]
- } catch {
- case _: ClassCastException => err(s"Applying '$coor' to '$newRoot' somehow resulted in '$result'")
- }
- }
-
- // TODO this logic is complicated, can any of it be unified with viewAs?
- // If `.viewAs` would capture its arguments, we could potentially use it
- // TODO Describe what this is doing at a high level
- private[chisel3] def cloneViewToContext[A, B <: Data](
- data: B,
- cache: HashMap[Data, Data],
- ioMap: Option[Map[Data, Data]],
- context: Option[BaseModule]
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): B = {
- // alias to shorten lookups
- def lookupData[C <: Data](d: C) = doLookupData(d, cache, ioMap, context)
-
- val result = data.cloneTypeFull
-
- // We have to lookup the target(s) of the view since they may need to be underlying into the current context
- val newBinding = data.topBinding match {
- case ViewBinding(target) => ViewBinding(lookupData(reify(target)))
- case avb @ AggregateViewBinding(map) =>
- data match {
- case e: Element => ViewBinding(lookupData(reify(avb.lookup(e).get)))
- case _: Aggregate =>
- // Provide a 1:1 mapping if possible
- val singleTargetOpt = map.get(data).filter(_ => avb == data.binding.get).flatMap(reifySingleData)
- singleTargetOpt match {
- case Some(singleTarget) => // It is 1:1!
- // This is a little tricky because the values in newMap need to point to Elements of newTarget
- val newTarget = lookupData(singleTarget)
- val newMap = coiterate(result, data).map {
- case (res, from) =>
- (res: Data) -> mapRootAndExtractSubField(map(from), _ => newTarget)
- }.toMap
- AggregateViewBinding(newMap + (result -> newTarget))
-
- case None => // No 1:1 mapping so we have to do a flat binding
- // Just remap each Element of this aggregate
- val newMap = coiterate(result, data).map {
- // Upcast res to Data since Maps are invariant in the Key type parameter
- case (res, from) => (res: Data) -> lookupData(reify(avb.lookup(from).get))
- }.toMap
- AggregateViewBinding(newMap)
- }
- }
- }
-
- // TODO Unify the following with `.viewAs`
- // We must also mark non-1:1 and child Aggregates in the view for renaming
- newBinding match {
- case _: ViewBinding => // Do nothing
- case AggregateViewBinding(childMap) =>
- if (!childMap.contains(result)) {
- Builder.unnamedViews += result
- }
- // Binding does not capture 1:1 for child aggregates views
- getRecursiveFields.lazily(result, "_").foreach {
- case (agg: Aggregate, _) if agg != result =>
- Builder.unnamedViews += agg
- case _ => // Do nothing
- }
- }
-
- result.bind(newBinding)
- result.setAllParents(Some(ViewParent))
- result.forceName("view", Builder.viewNamespace)
- result
- }
-
- /** Given a module (either original or a clone), clone it to a new context
- *
- * This function effectively recurses up the parents of module to find whether:
- * (1) A parent is already in the context; then we do nothing and return module
- * (2) A parent is in a different clone of the context; then we clone all the parents up
- * to that parent and set their parents to be in this underlying context
- * (3) A parent has no root; in that case, we do nothing and return the module.
- *
- * @param module original or clone to be underlying into a new context
- * @param context new context
- * @return original or clone in the new context
- */
- private[chisel3] def cloneModuleToContext[T <: BaseModule](
- module: Underlying[T],
- context: BaseModule
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Underlying[T] = {
- // Recursive call
- def rec[A <: BaseModule](m: A): Underlying[A] = {
- def clone(x: A, p: Option[BaseModule], name: () => String): Underlying[A] = {
- val newChild = Module.do_pseudo_apply(new internal.BaseModule.InstanceClone(x, name))
- newChild._parent = p
- Clone(newChild)
- }
- (m, context) match {
- case (c, ctx) if ctx == c => Proto(c)
- case (c, ctx: IsClone[_]) if ctx.hasSameProto(c) => Clone(ctx.asInstanceOf[IsClone[A]])
- case (c, ctx) if c._parent.isEmpty => Proto(c)
- case (_, _) =>
- cloneModuleToContext(Proto(m._parent.get), context) match {
- case Proto(p) => Proto(m)
- case Clone(p: BaseModule) =>
- clone(m, Some(p), () => m.instanceName)
- }
- }
- }
- module match {
- case Proto(m) => rec(m)
- case Clone(m: ModuleClone[_]) =>
- rec(m) match {
- case Proto(mx) => Clone(mx)
- case Clone(i: InstanceClone[_]) =>
- val newChild = Module.do_pseudo_apply(new InstanceClone(m.getProto, () => m.instanceName))
- newChild._parent = i._parent
- Clone(newChild)
- }
- case Clone(m: InstanceClone[_]) =>
- rec(m) match {
- case Proto(mx) => Clone(mx)
- case Clone(i: InstanceClone[_]) =>
- val newChild = Module.do_pseudo_apply(new InstanceClone(m.getProto, () => m.instanceName))
- newChild._parent = i._parent
- Clone(newChild)
- }
- }
- }
-
- class SimpleLookupable[X] extends Lookupable[X] {
- type B = X
- type C = X
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = that(definition.proto)
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = that(instance.proto)
- }
-
- implicit def lookupInstance[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
- new Lookupable[Instance[B]] {
- type C = Instance[B]
- def definitionLookup[A](that: A => Instance[B], definition: Definition[A]): C = {
- val ret = that(definition.proto)
- new Instance(cloneModuleToContext(ret.underlying, definition.getInnerDataContext.get))
- }
- def instanceLookup[A](that: A => Instance[B], instance: Instance[A]): C = {
- val ret = that(instance.proto)
- instance.underlying match {
- // If instance is just a normal module, no changing of context is necessary
- case Proto(_) => new Instance(ret.underlying)
- case Clone(_) => new Instance(cloneModuleToContext(ret.underlying, instance.getInnerDataContext.get))
- }
- }
- }
-
- implicit def lookupModule[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
- new Lookupable[B] {
- type C = Instance[B]
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
- val ret = that(definition.proto)
- new Instance(cloneModuleToContext(Proto(ret), definition.getInnerDataContext.get))
- }
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
- val ret = that(instance.proto)
- instance.underlying match {
- // If instance is just a normal module, no changing of context is necessary
- case Proto(_) => new Instance(Proto(ret))
- case Clone(_) => new Instance(cloneModuleToContext(Proto(ret), instance.getInnerDataContext.get))
- }
- }
- }
-
- implicit def lookupData[B <: Data](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
- new Lookupable[B] {
- type C = B
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
- val ret = that(definition.proto)
- if (isView(ret)) {
- ??? // TODO!!!!!! cloneViewToContext(ret, instance, ioMap, instance.getInnerDataContext)
- } else {
- doLookupData(ret, definition.cache, None, definition.getInnerDataContext)
- }
- }
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
- val ret = that(instance.proto)
-
- def getIoMap(hierarchy: Hierarchy[_]): Option[Map[Data, Data]] = {
- hierarchy.underlying match {
- case Clone(x: ModuleClone[_]) => Some(x.ioMap)
- case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap)
- case Clone(x: InstantiableClone[_]) => getIoMap(x._innerContext)
- case Clone(x: InstanceClone[_]) => None
- case other => {
- Builder.exception(s"Internal Error! Unexpected case where we can't get IO Map: $other")
- }
- }
- }
- val ioMap = getIoMap(instance)
-
- if (isView(ret)) {
- cloneViewToContext(ret, instance.cache, ioMap, instance.getInnerDataContext)
- } else {
- doLookupData(ret, instance.cache, ioMap, instance.getInnerDataContext)
- }
-
- }
- }
-
- private[chisel3] def cloneMemToContext[T <: MemBase[_]](
- mem: T,
- context: BaseModule
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): T = {
- mem._parent match {
- case None => mem
- case Some(parent) =>
- val newParent = cloneModuleToContext(Proto(parent), context)
- newParent match {
- case Proto(p) if p == parent => mem
- case Clone(mod: BaseModule) =>
- val existingMod = Builder.currentModule
- Builder.currentModule = Some(mod)
- val newChild: T = mem match {
- case m: Mem[_] => new Mem(m.t.asInstanceOf[Data].cloneTypeFull, m.length).asInstanceOf[T]
- case m: SyncReadMem[_] =>
- new SyncReadMem(m.t.asInstanceOf[Data].cloneTypeFull, m.length, m.readUnderWrite).asInstanceOf[T]
- }
- Builder.currentModule = existingMod
- newChild.setRef(mem.getRef, true)
- newChild
- }
- }
- }
-
- implicit def lookupMem[B <: MemBase[_]](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
- new Lookupable[B] {
- type C = B
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
- cloneMemToContext(that(definition.proto), definition.getInnerDataContext.get)
- }
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
- cloneMemToContext(that(instance.proto), instance.getInnerDataContext.get)
- }
- }
-
- import scala.language.higherKinds // Required to avoid warning for lookupIterable type parameter
- implicit def lookupIterable[B, F[_] <: Iterable[_]](
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions,
- lookupable: Lookupable[B]
- ) = new Lookupable[F[B]] {
- type C = F[lookupable.C]
- def definitionLookup[A](that: A => F[B], definition: Definition[A]): C = {
- val ret = that(definition.proto).asInstanceOf[Iterable[B]]
- ret.map { x: B => lookupable.definitionLookup[A](_ => x, definition) }.asInstanceOf[C]
- }
- def instanceLookup[A](that: A => F[B], instance: Instance[A]): C = {
- import instance._
- val ret = that(proto).asInstanceOf[Iterable[B]]
- ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) }.asInstanceOf[C]
- }
- }
- implicit def lookupOption[B](
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions,
- lookupable: Lookupable[B]
- ) = new Lookupable[Option[B]] {
- type C = Option[lookupable.C]
- def definitionLookup[A](that: A => Option[B], definition: Definition[A]): C = {
- val ret = that(definition.proto)
- ret.map { x: B => lookupable.definitionLookup[A](_ => x, definition) }
- }
- def instanceLookup[A](that: A => Option[B], instance: Instance[A]): C = {
- import instance._
- val ret = that(proto)
- ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) }
- }
- }
- implicit def lookupEither[L, R](
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions,
- lookupableL: Lookupable[L],
- lookupableR: Lookupable[R]
- ) = new Lookupable[Either[L, R]] {
- type C = Either[lookupableL.C, lookupableR.C]
- def definitionLookup[A](that: A => Either[L, R], definition: Definition[A]): C = {
- val ret = that(definition.proto)
- ret.map { x: R => lookupableR.definitionLookup[A](_ => x, definition) }.left.map { x: L =>
- lookupableL.definitionLookup[A](_ => x, definition)
- }
- }
- def instanceLookup[A](that: A => Either[L, R], instance: Instance[A]): C = {
- import instance._
- val ret = that(proto)
- ret.map { x: R => lookupableR.instanceLookup[A](_ => x, instance) }.left.map { x: L =>
- lookupableL.instanceLookup[A](_ => x, instance)
- }
- }
- }
-
- implicit def lookupTuple2[X, Y](
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions,
- lookupableX: Lookupable[X],
- lookupableY: Lookupable[Y]
- ) = new Lookupable[(X, Y)] {
- type C = (lookupableX.C, lookupableY.C)
- def definitionLookup[A](that: A => (X, Y), definition: Definition[A]): C = {
- val ret = that(definition.proto)
- (
- lookupableX.definitionLookup[A](_ => ret._1, definition),
- lookupableY.definitionLookup[A](_ => ret._2, definition)
- )
- }
- def instanceLookup[A](that: A => (X, Y), instance: Instance[A]): C = {
- import instance._
- val ret = that(proto)
- (lookupableX.instanceLookup[A](_ => ret._1, instance), lookupableY.instanceLookup[A](_ => ret._2, instance))
- }
- }
-
- implicit def lookupIsInstantiable[B <: IsInstantiable](
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ) = new Lookupable[B] {
- type C = Instance[B]
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
- val ret = that(definition.proto)
- val underlying = new InstantiableClone[B] {
- val getProto = ret
- lazy val _innerContext = definition
- }
- new Instance(Clone(underlying))
- }
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
- val ret = that(instance.proto)
- val underlying = new InstantiableClone[B] {
- val getProto = ret
- lazy val _innerContext = instance
- }
- new Instance(Clone(underlying))
- }
- }
-
- implicit def lookupIsLookupable[B <: IsLookupable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
- new SimpleLookupable[B]()
-
- implicit val lookupInt = new SimpleLookupable[Int]()
- implicit val lookupByte = new SimpleLookupable[Byte]()
- implicit val lookupShort = new SimpleLookupable[Short]()
- implicit val lookupLong = new SimpleLookupable[Long]()
- implicit val lookupFloat = new SimpleLookupable[Float]()
- implicit val lookupChar = new SimpleLookupable[Char]()
- implicit val lookupString = new SimpleLookupable[String]()
- implicit val lookupBoolean = new SimpleLookupable[Boolean]()
- implicit val lookupBigInt = new SimpleLookupable[BigInt]()
-}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Underlying.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Underlying.scala
deleted file mode 100644
index 864cc8af..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Underlying.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.experimental.hierarchy
-
-import chisel3.internal.BaseModule.IsClone
-
-/** Represents the underlying implementation of a Definition or Instance */
-sealed trait Underlying[+T]
-
-/** A clone of a real implementation */
-final case class Clone[+T](isClone: IsClone[T]) extends Underlying[T]
-
-/** An actual implementation */
-final case class Proto[+T](proto: T) extends Underlying[T]
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/package.scala b/core/src/main/scala/chisel3/experimental/hierarchy/package.scala
deleted file mode 100644
index c309ab52..00000000
--- a/core/src/main/scala/chisel3/experimental/hierarchy/package.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-package chisel3.experimental
-
-package object hierarchy {
-
- /** Classes or traits which will be used with the [[Definition]] + [[Instance]] api should be marked
- * with the [[@instantiable]] annotation at the class/trait definition.
- *
- * @example {{{
- * @instantiable
- * class MyModule extends Module {
- * ...
- * }
- *
- * val d = Definition(new MyModule)
- * val i0 = Instance(d)
- * val i1 = Instance(d)
- * }}}
- */
- class instantiable extends chisel3.internal.instantiable
-
- /** Classes marked with [[@instantiable]] can have their vals marked with the [[@public]] annotation to
- * enable accessing these values from a [[Definition]] or [[Instance]] of the class.
- *
- * Only vals of the the following types can be marked [[@public]]:
- * 1. IsInstantiable
- * 2. IsLookupable
- * 3. Data
- * 4. BaseModule
- * 5. Iterable/Option containing a type that meets these requirements
- * 6. Basic type like String, Int, BigInt etc.
- *
- * @example {{{
- * @instantiable
- * class MyModule extends Module {
- * @public val in = IO(Input(UInt(3.W)))
- * @public val out = IO(Output(UInt(3.W)))
- * ..
- * }
- *
- * val d = Definition(new MyModule)
- * val i0 = Instance(d)
- * val i1 = Instance(d)
- *
- * i1.in := i0.out
- * }}}
- */
- class public extends chisel3.internal.public
-}
diff --git a/core/src/main/scala/chisel3/experimental/package.scala b/core/src/main/scala/chisel3/experimental/package.scala
index 2b493aab..a69c5b6e 100644
--- a/core/src/main/scala/chisel3/experimental/package.scala
+++ b/core/src/main/scala/chisel3/experimental/package.scala
@@ -15,91 +15,16 @@ package object experimental {
import scala.language.implicitConversions
import chisel3.internal.BaseModule
- // Implicit conversions for BlackBox Parameters
- implicit def fromIntToIntParam(x: Int): IntParam = IntParam(BigInt(x))
- implicit def fromLongToIntParam(x: Long): IntParam = IntParam(BigInt(x))
- implicit def fromBigIntToIntParam(x: BigInt): IntParam = IntParam(x)
- implicit def fromDoubleToDoubleParam(x: Double): DoubleParam = DoubleParam(x)
- implicit def fromStringToStringParam(x: String): StringParam = StringParam(x)
-
@deprecated("This type has moved to chisel3", "Chisel 3.5")
type ChiselEnum = EnumFactory
// Rocket Chip-style clonemodule
- /** A record containing the results of CloneModuleAsRecord
- * The apply method is retrieves the element with the supplied name.
- */
- type ClonePorts = BaseModule.ClonePorts
-
- object CloneModuleAsRecord {
-
- /** Clones an existing module and returns a record of all its top-level ports.
- * Each element of the record is named with a string matching the
- * corresponding port's name and shares the port's type.
- * @example {{{
- * val q1 = Module(new Queue(UInt(32.W), 2))
- * val q2_io = CloneModuleAsRecord(q1)("io").asInstanceOf[q1.io.type]
- * q2_io.enq <> q1.io.deq
- * }}}
- */
- def apply(
- proto: BaseModule
- )(
- implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo,
- compileOptions: CompileOptions
- ): ClonePorts = {
- BaseModule.cloneIORecord(proto)
- }
- }
-
val requireIsHardware = chisel3.internal.requireIsHardware
val requireIsChiselType = chisel3.internal.requireIsChiselType
type Direction = ActualDirection
val Direction = ActualDirection
- /** The same as [[IO]] except there is no prefix for the name of the val */
- def FlatIO[T <: Record](gen: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = noPrefix {
- import dataview._
- def coerceDirection(d: Data) = {
- import chisel3.{SpecifiedDirection => SD}
- DataMirror.specifiedDirectionOf(gen) match {
- case SD.Flip => Flipped(d)
- case SD.Input => Input(d)
- case SD.Output => Output(d)
- case _ => d
- }
- }
- val ports: Seq[Data] =
- gen.elements.toSeq.reverse.map {
- case (name, data) =>
- val p = chisel3.IO(coerceDirection(chiselTypeClone(data).asInstanceOf[Data]))
- p.suggestName(name)
- p
-
- }
-
- implicit val dv: DataView[Seq[Data], T] = DataView.mapping(
- _ => chiselTypeClone(gen).asInstanceOf[T],
- (seq, rec) => seq.zip(rec.elements.toSeq.reverse).map { case (port, (_, field)) => port -> field }
- )
- ports.viewAs[T]
- }
-
- implicit class ChiselRange(val sc: StringContext) extends AnyVal {
-
- import scala.language.experimental.macros
-
- /** Specifies a range using mathematical range notation. Variables can be interpolated using
- * standard string interpolation syntax.
- * @example {{{
- * UInt(range"[0, 2)")
- * UInt(range"[0, \$myInt)")
- * UInt(range"[0, \${myInt + 2})")
- * }}}
- */
- def range(args: Any*): chisel3.internal.firrtl.IntervalRange = macro chisel3.internal.RangeTransform.apply
- }
class dump extends chisel3.internal.naming.dump
class treedump extends chisel3.internal.naming.treedump
diff --git a/core/src/main/scala/chisel3/internal/BiConnect.scala b/core/src/main/scala/chisel3/internal/BiConnect.scala
index 74376598..82835052 100644
--- a/core/src/main/scala/chisel3/internal/BiConnect.scala
+++ b/core/src/main/scala/chisel3/internal/BiConnect.scala
@@ -3,7 +3,6 @@
package chisel3.internal
import chisel3._
-import chisel3.experimental.dataview.{isView, reify, reifyToAggregate}
import chisel3.experimental.{attach, Analog, BaseModule}
import chisel3.internal.Builder.pushCommand
import chisel3.internal.firrtl.{Connect, Converter, DefInvalid}
@@ -79,7 +78,7 @@ private[chisel3] object BiConnect {
connectCompileOptions: CompileOptions,
left: Data,
right: Data,
- context_mod: RawModule
+ context_mod: BaseModule
): Unit = {
(left, right) match {
// Handle element case (root case)
@@ -109,27 +108,12 @@ private[chisel3] object BiConnect {
throw MismatchedVecException
}
- val leftReified: Option[Aggregate] = if (isView(left_v)) reifyToAggregate(left_v) else Some(left_v)
- val rightReified: Option[Aggregate] = if (isView(right_v)) reifyToAggregate(right_v) else Some(right_v)
-
- if (
- leftReified.nonEmpty && rightReified.nonEmpty && canBulkConnectAggregates(
- leftReified.get,
- rightReified.get,
- sourceInfo,
- connectCompileOptions,
- context_mod
- )
- ) {
- pushCommand(Connect(sourceInfo, leftReified.get.lref, rightReified.get.lref))
- } else {
- for (idx <- 0 until left_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, left_v(idx), right_v(idx), context_mod)
- } catch {
- case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
- }
+ for (idx <- 0 until left_v.length) {
+ try {
+ implicit val compileOptions = connectCompileOptions
+ connect(sourceInfo, connectCompileOptions, left_v(idx), right_v(idx), context_mod)
+ } catch {
+ case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
}
}
}
@@ -166,24 +150,7 @@ private[chisel3] object BiConnect {
!MonoConnect.canBeSink(left_r, context_mod) || !MonoConnect.canBeSource(right_r, context_mod)
val (newLeft, newRight) = if (flipConnection) (right_r, left_r) else (left_r, right_r)
- val leftReified: Option[Aggregate] = if (isView(newLeft)) reifyToAggregate(newLeft) else Some(newLeft)
- val rightReified: Option[Aggregate] = if (isView(newRight)) reifyToAggregate(newRight) else Some(newRight)
-
- if (
- leftReified.nonEmpty && rightReified.nonEmpty && canBulkConnectAggregates(
- leftReified.get,
- rightReified.get,
- sourceInfo,
- connectCompileOptions,
- context_mod
- )
- ) {
- pushCommand(Connect(sourceInfo, leftReified.get.lref, rightReified.get.lref))
- } else if (!emitStrictConnects) {
- newLeft.legacyConnect(newRight)(sourceInfo)
- } else {
- recordConnect(sourceInfo, connectCompileOptions, left_r, right_r, context_mod)
- }
+ recordConnect(sourceInfo, connectCompileOptions, left_r, right_r, context_mod)
// Handle Records connected to DontCare
case (left_r: Record, DontCare) =>
@@ -224,7 +191,7 @@ private[chisel3] object BiConnect {
connectCompileOptions: CompileOptions,
left_r: Record,
right_r: Record,
- context_mod: RawModule
+ context_mod: BaseModule
): Unit = {
// Verify right has no extra fields that left doesn't have
@@ -270,7 +237,7 @@ private[chisel3] object BiConnect {
source: Aggregate,
sourceInfo: SourceInfo,
connectCompileOptions: CompileOptions,
- context_mod: RawModule
+ context_mod: BaseModule
): Boolean = {
// check that the aggregates have the same types
@@ -304,13 +271,7 @@ private[chisel3] object BiConnect {
case _ => true
}
- // do not bulk connect the 'io' pseudo-bundle of a BlackBox since it will be decomposed in FIRRTL
- def blackBoxCheck = Seq(source, sink).map(_._parent).forall {
- case Some(_: BlackBox) => false
- case _ => true
- }
-
- typeCheck && contextCheck && bindingCheck && flow_check && sourceNotLiteralCheck && blackBoxCheck
+ typeCheck && contextCheck && bindingCheck && flow_check && sourceNotLiteralCheck
}
// These functions (finally) issue the connection operation
@@ -344,11 +305,11 @@ private[chisel3] object BiConnect {
connectCompileOptions: CompileOptions,
_left: Element,
_right: Element,
- context_mod: RawModule
+ context_mod: BaseModule
): Unit = {
import BindingDirection.{Input, Internal, Output} // Using extensively so import these
- val left = reify(_left)
- val right = reify(_right)
+ val left = _left
+ val right = _right
// If left or right have no location, assume in context module
// This can occur if one of them is a literal, unbound will error previously
val left_mod: BaseModule = left.topBinding.location.getOrElse(context_mod)
@@ -451,7 +412,7 @@ private[chisel3] object BiConnect {
}
// This function checks if analog element-level attaching is allowed, then marks the Analog as connected
- def markAnalogConnected(implicit sourceInfo: SourceInfo, analog: Analog, contextModule: RawModule): Unit = {
+ def markAnalogConnected(implicit sourceInfo: SourceInfo, analog: Analog, contextModule: BaseModule): Unit = {
analog.biConnectLocs.get(contextModule) match {
case Some(sl) => throw AttachAlreadyBulkConnectedException(sl)
case None => // Do nothing
diff --git a/core/src/main/scala/chisel3/internal/Binding.scala b/core/src/main/scala/chisel3/internal/Binding.scala
index bab79bc1..63936212 100644
--- a/core/src/main/scala/chisel3/internal/Binding.scala
+++ b/core/src/main/scala/chisel3/internal/Binding.scala
@@ -82,15 +82,7 @@ sealed trait UnconstrainedBinding extends TopBinding {
// Location will track where this Module is, and the bound object can be referenced in FIRRTL
sealed trait ConstrainedBinding extends TopBinding {
def enclosure: BaseModule
- def location: Option[BaseModule] = {
- // If an aspect is present, return the aspect module. Otherwise, return the enclosure module
- // This allows aspect modules to pretend to be enclosed modules for connectivity checking,
- // inside vs outside instance checking, etc.
- Builder.aspectModule(enclosure) match {
- case None => Some(enclosure)
- case Some(aspect) => Some(aspect)
- }
- }
+ def location: Option[BaseModule] = Some(enclosure)
}
// A binding representing a data that cannot be (re)assigned to.
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index ab1435c5..57f878aa 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -6,13 +6,11 @@ import scala.util.DynamicVariable
import scala.collection.mutable.ArrayBuffer
import chisel3._
import chisel3.experimental._
-import chisel3.experimental.hierarchy.{Clone, ImportDefinitionAnnotation, Instance}
import chisel3.internal.firrtl._
import chisel3.internal.naming._
import _root_.firrtl.annotations.{CircuitName, ComponentName, IsMember, ModuleName, Named, ReferenceTarget}
import _root_.firrtl.annotations.AnnotationUtils.validComponentName
import _root_.firrtl.{AnnotationSeq, RenameMap}
-import chisel3.experimental.dataview.{reify, reifySingleData}
import chisel3.internal.Builder.Prefix
import logger.LazyLogging
@@ -316,7 +314,6 @@ private[chisel3] trait HasId extends InstanceId {
}
val parentGuess: String = _parent match {
- case Some(ViewParent) => s", in module '${reifyParent.pathName}'"
case Some(p) => s", in module '${p.pathName}'"
case None => ""
}
@@ -324,18 +321,8 @@ private[chisel3] trait HasId extends InstanceId {
nameGuess + parentGuess
}
- // Helper for reifying views if they map to a single Target
- private[chisel3] def reifyTarget: Option[Data] = this match {
- case d: Data => reifySingleData(d) // Only Data can be views
- case bad => throwException(s"This shouldn't be possible - got $bad with ${_parent}")
- }
-
- // Helper for reifying the parent of a view if the view maps to a single Target
- private[chisel3] def reifyParent: BaseModule = reifyTarget.flatMap(_._parent).getOrElse(ViewParent)
-
// Implementation of public methods.
def instanceName: String = _parent match {
- case Some(ViewParent) => reifyTarget.map(_.instanceName).getOrElse(this.refName(ViewParent.fakeComponent))
case Some(p) =>
(p._component, this) match {
case (Some(c), _) => refName(c)
@@ -348,16 +335,13 @@ private[chisel3] trait HasId extends InstanceId {
}
def pathName: String = _parent match {
case None => instanceName
- case Some(ViewParent) => s"${reifyParent.pathName}.$instanceName"
case Some(p) => s"${p.pathName}.$instanceName"
}
def parentPathName: String = _parent match {
- case Some(ViewParent) => reifyParent.pathName
case Some(p) => p.pathName
case None => throwException(s"$instanceName doesn't have a parent")
}
def parentModName: String = _parent match {
- case Some(ViewParent) => reifyParent.name
case Some(p) => p.name
case None => throwException(s"$instanceName doesn't have a parent")
}
@@ -368,7 +352,6 @@ private[chisel3] trait HasId extends InstanceId {
case None => instanceName
case Some(o) => o.circuitName
}
- case Some(ViewParent) => reifyParent.circuitName
case Some(p) => p.circuitName
}
@@ -413,7 +396,6 @@ private[chisel3] trait NamedComponent extends HasId {
if (!validComponentName(name)) throwException(s"Illegal component name: $name (note: literals are illegal)")
import _root_.firrtl.annotations.{Target, TargetToken}
val root = _parent.map {
- case ViewParent => reifyParent
case other => other
}.get.getTarget // All NamedComponents will have a parent, only the top module can have None here
Target.toTargetTokens(name).toList match {
@@ -427,7 +409,6 @@ private[chisel3] trait NamedComponent extends HasId {
val localTarget = toTarget
def makeTarget(p: BaseModule) = p.toAbsoluteTarget.ref(localTarget.ref).copy(component = localTarget.component)
_parent match {
- case Some(ViewParent) => makeTarget(reifyParent)
case Some(parent) => makeTarget(parent)
case None => localTarget
}
@@ -455,11 +436,6 @@ private[chisel3] class ChiselContext() {
// Records the different prefixes which have been scoped at this point in time
var prefixStack: Prefix = Nil
-
- // Views belong to a separate namespace (for renaming)
- // The namespace outside of Builder context is useless, but it ensures that views can still be created
- // and the resulting .toTarget is very clearly useless (_$$View$$_...)
- val viewNamespace = Namespace.empty
}
private[chisel3] class DynamicContext(
@@ -467,43 +443,9 @@ private[chisel3] class DynamicContext(
val throwOnFirstError: Boolean,
val warnReflectiveNaming: Boolean,
val warningsAsErrors: Boolean) {
- val importDefinitionAnnos = annotationSeq.collect { case a: ImportDefinitionAnnotation[_] => a }
-
- // Map holding the actual names of extModules
- // Pick the definition name by default in case not passed through annotation.
- val importDefinitionMap = importDefinitionAnnos
- .map(a => a.definition.proto.name -> a.overrideDefName.getOrElse(a.definition.proto.name))
- .toMap
-
- // Helper function which does 2 things
- // 1. Ensure there are no repeated names for imported Definitions - both Proto Names as well as ExtMod Names
- // 2. Return the distinct definition / extMod names
- private def checkAndGeDistinctProtoExtModNames() = {
- val importAllDefinitionProtoNames = importDefinitionAnnos.map { a => a.definition.proto.name }
- val importDistinctDefinitionProtoNames = importDefinitionMap.keys.toSeq
- val importAllDefinitionExtModNames = importDefinitionMap.toSeq.map(_._2)
- val importDistinctDefinitionExtModNames = importAllDefinitionExtModNames.distinct
-
- if (importDistinctDefinitionProtoNames.length < importAllDefinitionProtoNames.length) {
- val duplicates = importAllDefinitionProtoNames.diff(importDistinctDefinitionProtoNames).mkString(", ")
- throwException(s"Expected distinct imported Definition names but found duplicates for: $duplicates")
- }
- if (importDistinctDefinitionExtModNames.length < importAllDefinitionExtModNames.length) {
- val duplicates = importAllDefinitionExtModNames.diff(importDistinctDefinitionExtModNames).mkString(", ")
- throwException(s"Expected distinct overrideDef names but found duplicates for: $duplicates")
- }
- (importAllDefinitionProtoNames ++ importAllDefinitionExtModNames).distinct
- }
val globalNamespace = Namespace.empty
- // Ensure imported Definitions emit as ExtModules with the correct name so
- // that instantiations will also use the correct name and prevent any name
- // conflicts with Modules/Definitions in this elaboration
- checkAndGeDistinctProtoExtModNames().foreach {
- globalNamespace.name(_)
- }
-
val components = ArrayBuffer[Component]()
val annotations = ArrayBuffer[ChiselAnnotation]()
val newAnnotations = ArrayBuffer[ChiselMultiAnnotation]()
@@ -518,9 +460,6 @@ private[chisel3] class DynamicContext(
*/
val aspectModule: mutable.HashMap[BaseModule, BaseModule] = mutable.HashMap.empty[BaseModule, BaseModule]
- // Views that do not correspond to a single ReferenceTarget and thus require renaming
- val unnamedViews: ArrayBuffer[Data] = ArrayBuffer.empty
-
// Set by object Module.apply before calling class Module constructor
// Used to distinguish between no Module() wrapping, multiple wrappings, and rewrapping
var readyForModuleConstr: Boolean = false
@@ -529,9 +468,6 @@ private[chisel3] class DynamicContext(
var currentReset: Option[Reset] = None
val errors = new ErrorLog(warningsAsErrors)
val namingStack = new NamingStack
-
- // Used to indicate if this is the top-level module of full elaboration, or from a Definition
- var inDefinition: Boolean = false
}
private[chisel3] object Builder extends LazyLogging {
@@ -588,10 +524,6 @@ private[chisel3] object Builder extends LazyLogging {
def annotationSeq: AnnotationSeq = dynamicContext.annotationSeq
def namingStack: NamingStack = dynamicContext.namingStack
- def importDefinitionMap: Map[String, String] = dynamicContext.importDefinitionMap
-
- def unnamedViews: ArrayBuffer[Data] = dynamicContext.unnamedViews
- def viewNamespace: Namespace = chiselContext.get.viewNamespace
// Puts a prefix string onto the prefix stack
def pushPrefix(d: String): Unit = {
@@ -612,7 +544,6 @@ private[chisel3] object Builder extends LazyLogging {
case Index(_, ILit(n)) => Some(n.toString) // Vec static indexing
case Index(_, ULit(n, _)) => Some(n.toString) // Vec lit indexing
case Index(_, _: Node) => None // Vec dynamic indexing
- case ModuleIO(_, n) => Some(n) // BlackBox port
}
def map2[A, B](a: Option[A], b: Option[A])(f: (A, A) => B): Option[B] =
a.flatMap(ax => b.map(f(ax, _)))
@@ -628,7 +559,6 @@ private[chisel3] object Builder extends LazyLogging {
case PortBinding(mod) if Builder.currentModule.contains(mod) => data.seedOpt
case PortBinding(mod) => map2(mod.seedOpt, data.seedOpt)(_ + "_" + _)
case (_: LitBinding | _: DontCareBinding) => None
- case _ => Some("view_") // TODO implement
}
id match {
case d: Data => recData(d)
@@ -672,10 +602,7 @@ private[chisel3] object Builder extends LazyLogging {
def currentModule_=(target: Option[BaseModule]): Unit = {
dynamicContext.currentModule = target
}
- def aspectModule(module: BaseModule): Option[BaseModule] = dynamicContextVar.value match {
- case Some(dynamicContext) => dynamicContext.aspectModule.get(module)
- case _ => None
- }
+
/** Retrieves the parent of a module based on the elaboration context
*
@@ -683,25 +610,8 @@ private[chisel3] object Builder extends LazyLogging {
* @param context the context the parent should be evaluated in
* @return the parent of the module provided
*/
- def retrieveParent(module: BaseModule, context: BaseModule): Option[BaseModule] = {
- module._parent match {
- case Some(parentModule) => { //if a parent exists investigate, otherwise return None
- context match {
- case aspect: ModuleAspect => { //if aspect context, do the translation
- Builder.aspectModule(parentModule) match {
- case Some(parentAspect) => Some(parentAspect) //we've found a translation
- case _ => Some(parentModule) //no translation found
- }
- } //otherwise just return our parent
- case _ => Some(parentModule)
- }
- }
- case _ => None
- }
- }
- def addAspect(module: BaseModule, aspect: BaseModule): Unit = {
- dynamicContext.aspectModule += ((module, aspect))
- }
+ def retrieveParent(module: BaseModule, context: BaseModule): Option[BaseModule] = module._parent
+
def forcedModule: BaseModule = currentModule match {
case Some(module) => module
case None =>
@@ -710,20 +620,7 @@ private[chisel3] object Builder extends LazyLogging {
// A bare api call is, e.g. calling Wire() from the scala console).
)
}
- def referenceUserModule: RawModule = {
- currentModule match {
- case Some(module: RawModule) =>
- aspectModule(module) match {
- case Some(aspect: RawModule) => aspect
- case other => module
- }
- case _ =>
- throwException(
- "Error: Not in a RawModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox."
- // A bare api call is, e.g. calling Wire() from the scala console).
- )
- }
- }
+
def forcedUserModule: RawModule = currentModule match {
case Some(module: RawModule) => module
case _ =>
@@ -768,12 +665,6 @@ private[chisel3] object Builder extends LazyLogging {
dynamicContext.currentReset = newReset
}
- def inDefinition: Boolean = {
- dynamicContextVar.value
- .map(_.inDefinition)
- .getOrElse(false)
- }
-
def forcedClock: Clock = currentClock.getOrElse(
throwException("Error: No implicit clock.")
)
@@ -801,11 +692,6 @@ private[chisel3] object Builder extends LazyLogging {
* (Note: Map is Iterable[Tuple2[_,_]] and thus excluded)
*/
def nameRecursively(prefix: String, nameMe: Any, namer: (HasId, String) => Unit): Unit = nameMe match {
- case (id: Instance[_]) =>
- id.underlying match {
- case Clone(m: internal.BaseModule.ModuleClone[_]) => namer(m.getPorts, prefix)
- case _ =>
- }
case (id: HasId) => namer(id, prefix)
case Some(elt) => nameRecursively(prefix, elt, namer)
case (iter: Iterable[_]) if iter.hasDefiniteSize =>
@@ -853,31 +739,12 @@ private[chisel3] object Builder extends LazyLogging {
}
}
- // Builds a RenameMap for all Views that do not correspond to a single Data
- // These Data give a fake ReferenceTarget for .toTarget and .toReferenceTarget that the returned
- // RenameMap can split into the constituent parts
- private[chisel3] def makeViewRenameMap: RenameMap = {
- val renames = RenameMap()
- for (view <- unnamedViews) {
- val localTarget = view.toTarget
- val absTarget = view.toAbsoluteTarget
- val elts = getRecursiveFields.lazily(view, "").collect { case (elt: Element, _) => elt }
- for (elt <- elts) {
- val targetOfView = reify(elt)
- renames.record(localTarget, targetOfView.toTarget)
- renames.record(absTarget, targetOfView.toAbsoluteTarget)
- }
- }
- renames
- }
-
private[chisel3] def build[T <: BaseModule](
f: => T,
dynamicContext: DynamicContext,
forceModName: Boolean = true
): (Circuit, T) = {
dynamicContextVar.withValue(Some(dynamicContext)) {
- ViewParent // Must initialize the singleton in a Builder context or weird things can happen
// in tiny designs/testcases that never access anything in chisel3.internal
checkScalaVersion()
logger.info("Elaborating design...")
@@ -888,7 +755,7 @@ private[chisel3] object Builder extends LazyLogging {
errors.checkpoint(logger)
logger.info("Done elaborating.")
- (Circuit(components.last.name, components.toSeq, annotations.toSeq, makeViewRenameMap, newAnnotations.toSeq), mod)
+ (Circuit(components.last.name, components.toSeq, annotations.toSeq, null, newAnnotations.toSeq), mod)
}
}
initializeSingletons()
diff --git a/core/src/main/scala/chisel3/internal/MonoConnect.scala b/core/src/main/scala/chisel3/internal/MonoConnect.scala
index a0cca4a6..257c543f 100644
--- a/core/src/main/scala/chisel3/internal/MonoConnect.scala
+++ b/core/src/main/scala/chisel3/internal/MonoConnect.scala
@@ -3,10 +3,9 @@
package chisel3.internal
import chisel3._
-import chisel3.experimental.{Analog, BaseModule, FixedPoint, Interval, UnsafeEnum}
+import chisel3.experimental.{Analog, BaseModule, UnsafeEnum}
import chisel3.internal.Builder.pushCommand
import chisel3.internal.firrtl.{Connect, Converter, DefInvalid}
-import chisel3.experimental.dataview.{isView, reify, reifyToAggregate}
import scala.language.experimental.macros
import chisel3.internal.sourceinfo.SourceInfo
@@ -96,7 +95,7 @@ private[chisel3] object MonoConnect {
connectCompileOptions: CompileOptions,
sink: Data,
source: Data,
- context_mod: RawModule
+ context_mod: BaseModule
): Unit =
(sink, source) match {
@@ -109,10 +108,6 @@ private[chisel3] object MonoConnect {
elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
case (sink_e: SInt, source_e: SInt) =>
elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: FixedPoint, source_e: FixedPoint) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: Interval, source_e: Interval) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
case (sink_e: Clock, source_e: Clock) =>
elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
case (sink_e: AsyncReset, source_e: AsyncReset) =>
@@ -131,28 +126,12 @@ private[chisel3] object MonoConnect {
// Handle Vec case
case (sink_v: Vec[Data @unchecked], source_v: Vec[Data @unchecked]) =>
if (sink_v.length != source_v.length) { throw MismatchedVecException }
-
- val sinkReified: Option[Aggregate] = if (isView(sink_v)) reifyToAggregate(sink_v) else Some(sink_v)
- val sourceReified: Option[Aggregate] = if (isView(source_v)) reifyToAggregate(source_v) else Some(source_v)
-
- if (
- sinkReified.nonEmpty && sourceReified.nonEmpty && canBulkConnectAggregates(
- sinkReified.get,
- sourceReified.get,
- sourceInfo,
- connectCompileOptions,
- context_mod
- )
- ) {
- pushCommand(Connect(sourceInfo, sinkReified.get.lref, sourceReified.get.ref))
- } else {
- for (idx <- 0 until sink_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod)
- } catch {
- case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message")
- }
+ for (idx <- 0 until sink_v.length) {
+ try {
+ implicit val compileOptions = connectCompileOptions
+ connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod)
+ } catch {
+ case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message")
}
}
// Handle Vec connected to DontCare. Apply the DontCare to individual elements.
@@ -168,34 +147,19 @@ private[chisel3] object MonoConnect {
// Handle Record case
case (sink_r: Record, source_r: Record) =>
- val sinkReified: Option[Aggregate] = if (isView(sink_r)) reifyToAggregate(sink_r) else Some(sink_r)
- val sourceReified: Option[Aggregate] = if (isView(source_r)) reifyToAggregate(source_r) else Some(source_r)
-
- if (
- sinkReified.nonEmpty && sourceReified.nonEmpty && canBulkConnectAggregates(
- sinkReified.get,
- sourceReified.get,
- sourceInfo,
- connectCompileOptions,
- context_mod
- )
- ) {
- pushCommand(Connect(sourceInfo, sinkReified.get.lref, sourceReified.get.ref))
- } else {
- // For each field, descend with right
- for ((field, sink_sub) <- sink_r.elements) {
- try {
- source_r.elements.get(field) match {
- case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod)
- case None => {
- if (connectCompileOptions.connectFieldsMustMatch) {
- throw MissingFieldException(field)
- }
+ // For each field, descend with right
+ for ((field, sink_sub) <- sink_r.elements) {
+ try {
+ source_r.elements.get(field) match {
+ case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod)
+ case None => {
+ if (connectCompileOptions.connectFieldsMustMatch) {
+ throw MissingFieldException(field)
}
}
- } catch {
- case MonoConnectException(message) => throw MonoConnectException(s".$field$message")
}
+ } catch {
+ case MonoConnectException(message) => throw MonoConnectException(s".$field$message")
}
}
// Handle Record connected to DontCare. Apply the DontCare to individual elements.
@@ -210,8 +174,7 @@ private[chisel3] object MonoConnect {
}
// Source is DontCare - it may be connected to anything. It generates a defInvalid for the sink.
- case (_sink: Element, DontCare) =>
- val sink = reify(_sink) // Handle views
+ case (sink: Element, DontCare) =>
pushCommand(DefInvalid(sourceInfo, sink.lref))
// DontCare as a sink is illegal.
case (DontCare, _) => throw DontCareCantBeSink
@@ -235,7 +198,7 @@ private[chisel3] object MonoConnect {
connectCompileOptions: CompileOptions,
sink: Aggregate,
source: Aggregate,
- context_mod: RawModule
+ context_mod: BaseModule
): Boolean = {
import ActualDirection.{Bidirectional, Input, Output}
// If source has no location, assume in context module
@@ -334,7 +297,7 @@ private[chisel3] object MonoConnect {
wantToBeSink: Boolean,
currentlyFlipped: Boolean,
data: Data,
- context_mod: RawModule
+ context_mod: BaseModule
): Boolean = {
val sdir = data.specifiedDirection
val coercedFlip = sdir == SpecifiedDirection.Input
@@ -349,8 +312,8 @@ private[chisel3] object MonoConnect {
case _ => true
}
}
- def canBeSink(data: Data, context_mod: RawModule): Boolean = traceFlow(true, false, data, context_mod)
- def canBeSource(data: Data, context_mod: RawModule): Boolean = traceFlow(false, false, data, context_mod)
+ def canBeSink(data: Data, context_mod: BaseModule): Boolean = traceFlow(true, false, data, context_mod)
+ def canBeSource(data: Data, context_mod: BaseModule): Boolean = traceFlow(false, false, data, context_mod)
/** Check whether two aggregates can be bulk connected (<=) in FIRRTL. (MonoConnect case)
*
@@ -363,7 +326,7 @@ private[chisel3] object MonoConnect {
source: Aggregate,
sourceInfo: SourceInfo,
connectCompileOptions: CompileOptions,
- context_mod: RawModule
+ context_mod: BaseModule
): Boolean = {
// Assuming we're using a <>, check if a bulk connect is valid in that case
def biConnectCheck =
@@ -391,13 +354,11 @@ private[chisel3] object MonoConnect {
def elemConnect(
implicit sourceInfo: SourceInfo,
connectCompileOptions: CompileOptions,
- _sink: Element,
- _source: Element,
- context_mod: RawModule
+ sink: Element,
+ source: Element,
+ context_mod: BaseModule
): Unit = {
import BindingDirection.{Input, Internal, Output} // Using extensively so import these
- val sink = reify(_sink)
- val source = reify(_source)
// If source has no location, assume in context module
// This can occur if is a literal, unbound will error previously
val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException(sink, source))
diff --git a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
index ca39608f..c9719498 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
@@ -90,16 +90,6 @@ private[chisel3] object Converter {
val uint = convert(ULit(unsigned, slit.width), ctx, info)
fir.DoPrim(firrtl.PrimOps.AsSInt, Seq(uint), Seq.empty, fir.UnknownType)
// TODO Simplify
- case fplit @ FPLit(n, w, bp) =>
- val unsigned = if (n < 0) (BigInt(1) << fplit.width.get) + n else n
- val uint = convert(ULit(unsigned, fplit.width), ctx, info)
- val lit = bp.asInstanceOf[KnownBinaryPoint].value
- fir.DoPrim(firrtl.PrimOps.AsFixedPoint, Seq(uint), Seq(lit), fir.UnknownType)
- case intervalLit @ IntervalLit(n, w, bp) =>
- val unsigned = if (n < 0) (BigInt(1) << intervalLit.width.get) + n else n
- val uint = convert(ULit(unsigned, intervalLit.width), ctx, info)
- val lit = bp.asInstanceOf[KnownBinaryPoint].value
- fir.DoPrim(firrtl.PrimOps.AsInterval, Seq(uint), Seq(n, n, lit), fir.UnknownType)
case lit: ILit =>
throwException(s"Internal Error! Unexpected ILit: $lit")
}
@@ -319,8 +309,6 @@ private[chisel3] object Converter {
case d: EnumType => fir.UIntType(convert(d.width))
case d: UInt => fir.UIntType(convert(d.width))
case d: SInt => fir.SIntType(convert(d.width))
- case d: FixedPoint => fir.FixedType(convert(d.width), convert(d.binaryPoint))
- case d: Interval => fir.IntervalType(d.range.lowerBound, d.range.upperBound, d.range.firrtlBinaryPoint)
case d: Analog => fir.AnalogType(convert(d.width))
case d: Vec[_] =>
val childClearDir = clearDir ||
@@ -343,13 +331,6 @@ private[chisel3] object Converter {
}
}
- def convert(name: String, param: Param): fir.Param = param match {
- case IntParam(value) => fir.IntParam(name, value)
- case DoubleParam(value) => fir.DoubleParam(name, value)
- case StringParam(value) => fir.StringParam(name, fir.StringLit(value))
- case RawParam(value) => fir.RawStringParam(name, value)
- }
-
def convert(port: Port, topDir: SpecifiedDirection = SpecifiedDirection.Unspecified): fir.Port = {
val resolvedDir = SpecifiedDirection.fromParent(topDir, port.dir)
val dir = resolvedDir match {
@@ -368,14 +349,6 @@ private[chisel3] object Converter {
def convert(component: Component): fir.DefModule = component match {
case ctx @ DefModule(_, name, ports, cmds) =>
fir.Module(fir.NoInfo, name, ports.map(p => convert(p)), convert(cmds, ctx))
- case ctx @ DefBlackBox(id, name, ports, topDir, params) =>
- fir.ExtModule(
- fir.NoInfo,
- name,
- ports.map(p => convert(p, topDir)),
- id.desiredName,
- params.map { case (name, p) => convert(name, p) }.toSeq
- )
}
def convert(circuit: Circuit): fir.Circuit =
diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
index ddad6b10..8ed5ed07 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -53,7 +53,6 @@ object PrimOp {
val AsUIntOp = PrimOp("asUInt")
val AsSIntOp = PrimOp("asSInt")
val AsFixedPointOp = PrimOp("asFixedPoint")
- val AsIntervalOp = PrimOp("asInterval")
val WrapOp = PrimOp("wrap")
val SqueezeOp = PrimOp("squz")
val ClipOp = PrimOp("clip")
@@ -168,25 +167,6 @@ case class FPLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends LitArg(n
}
}
-case class IntervalLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends LitArg(n, w) {
- def name: String = {
- val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n
- s"asInterval(${ULit(unsigned, width).name}, ${n}, ${n}, ${binaryPoint.asInstanceOf[KnownBinaryPoint].value})"
- }
- val range: IntervalRange = {
- new IntervalRange(
- IntervalRange.getBound(isClosed = true, BigDecimal(n)),
- IntervalRange.getBound(isClosed = true, BigDecimal(n)),
- IntervalRange.getRangeWidth(binaryPoint)
- )
- }
- def minWidth: Int = 1 + n.bitLength
-
- def cloneWithWidth(newWidth: Width): this.type = {
- IntervalLit(n, newWidth, binaryPoint).asInstanceOf[this.type]
- }
-}
-
case class Ref(name: String) extends Arg
/** Arg for ports of Modules
@@ -314,483 +294,6 @@ object MemPortDirection {
object INFER extends MemPortDirection("infer")
}
-sealed trait RangeType {
- def getWidth: Width
-
- def *(that: IntervalRange): IntervalRange
- def +&(that: IntervalRange): IntervalRange
- def -&(that: IntervalRange): IntervalRange
- def <<(that: Int): IntervalRange
- def >>(that: Int): IntervalRange
- def <<(that: KnownWidth): IntervalRange
- def >>(that: KnownWidth): IntervalRange
- def merge(that: IntervalRange): IntervalRange
-}
-
-object IntervalRange {
-
- /** Creates an IntervalRange, this is used primarily by the range interpolator macro
- * @param lower lower bound
- * @param upper upper bound
- * @param firrtlBinaryPoint binary point firrtl style
- * @return
- */
- def apply(lower: firrtlir.Bound, upper: firrtlir.Bound, firrtlBinaryPoint: firrtlir.Width): IntervalRange = {
- new IntervalRange(lower, upper, firrtlBinaryPoint)
- }
-
- def apply(lower: firrtlir.Bound, upper: firrtlir.Bound, binaryPoint: BinaryPoint): IntervalRange = {
- new IntervalRange(lower, upper, IntervalRange.getBinaryPoint(binaryPoint))
- }
-
- def apply(lower: firrtlir.Bound, upper: firrtlir.Bound, binaryPoint: Int): IntervalRange = {
- IntervalRange(lower, upper, BinaryPoint(binaryPoint))
- }
-
- /** Returns an IntervalRange appropriate for a signed value of the given width
- * @param binaryPoint number of bits of mantissa
- * @return
- */
- def apply(binaryPoint: BinaryPoint): IntervalRange = {
- IntervalRange(firrtlir.UnknownBound, firrtlir.UnknownBound, binaryPoint)
- }
-
- /** Returns an IntervalRange appropriate for a signed value of the given width
- * @param width number of bits to have in the interval
- * @param binaryPoint number of bits of mantissa
- * @return
- */
- def apply(width: Width, binaryPoint: BinaryPoint = 0.BP): IntervalRange = {
- val range = width match {
- case KnownWidth(w) =>
- val nearestPowerOf2 = BigInt("1" + ("0" * (w - 1)), 2)
- IntervalRange(
- firrtlir.Closed(BigDecimal(-nearestPowerOf2)),
- firrtlir.Closed(BigDecimal(nearestPowerOf2 - 1)),
- binaryPoint
- )
- case _ =>
- IntervalRange(firrtlir.UnknownBound, firrtlir.UnknownBound, binaryPoint)
- }
- range
- }
-
- def unapply(arg: IntervalRange): Option[(firrtlir.Bound, firrtlir.Bound, BinaryPoint)] = {
- return Some((arg.lower, arg.upper, arg.binaryPoint))
- }
-
- def getBound(isClosed: Boolean, value: String): firrtlir.Bound = {
- if (value == "?") {
- firrtlir.UnknownBound
- } else if (isClosed) {
- firrtlir.Closed(BigDecimal(value))
- } else {
- firrtlir.Open(BigDecimal(value))
- }
- }
-
- def getBound(isClosed: Boolean, value: BigDecimal): firrtlir.Bound = {
- if (isClosed) {
- firrtlir.Closed(value)
- } else {
- firrtlir.Open(value)
- }
- }
-
- def getBound(isClosed: Boolean, value: Int): firrtlir.Bound = {
- getBound(isClosed, (BigDecimal(value)))
- }
-
- def getBinaryPoint(s: String): firrtlir.Width = {
- firrtlir.UnknownWidth
- }
-
- def getBinaryPoint(n: Int): firrtlir.Width = {
- if (n < 0) {
- firrtlir.UnknownWidth
- } else {
- firrtlir.IntWidth(n)
- }
- }
- def getBinaryPoint(n: BinaryPoint): firrtlir.Width = {
- n match {
- case UnknownBinaryPoint => firrtlir.UnknownWidth
- case KnownBinaryPoint(w) => firrtlir.IntWidth(w)
- }
- }
-
- def getRangeWidth(w: Width): firrtlir.Width = {
- if (w.known) {
- firrtlir.IntWidth(w.get)
- } else {
- firrtlir.UnknownWidth
- }
- }
- def getRangeWidth(binaryPoint: BinaryPoint): firrtlir.Width = {
- if (binaryPoint.known) {
- firrtlir.IntWidth(binaryPoint.get)
- } else {
- firrtlir.UnknownWidth
- }
- }
-
- def Unknown: IntervalRange = range"[?,?].?"
-}
-
-sealed class IntervalRange(
- val lowerBound: firrtlir.Bound,
- val upperBound: firrtlir.Bound,
- private[chisel3] val firrtlBinaryPoint: firrtlir.Width)
- extends firrtlir.IntervalType(lowerBound, upperBound, firrtlBinaryPoint)
- with RangeType {
-
- (lowerBound, upperBound) match {
- case (firrtlir.Open(begin), firrtlir.Open(end)) =>
- if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}")
- binaryPoint match {
- case KnownBinaryPoint(bp) =>
- if (begin >= end - (BigDecimal(1) / BigDecimal(BigInt(1) << bp))) {
- throw new ChiselException(s"Invalid range with ${serialize}")
- }
- case _ =>
- }
- case (firrtlir.Open(begin), firrtlir.Closed(end)) =>
- if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}")
- case (firrtlir.Closed(begin), firrtlir.Open(end)) =>
- if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}")
- case (firrtlir.Closed(begin), firrtlir.Closed(end)) =>
- if (begin > end) throw new ChiselException(s"Invalid range with ${serialize}")
- case _ =>
- }
-
- override def toString: String = {
- val binaryPoint = firrtlBinaryPoint match {
- case firrtlir.IntWidth(n) => s"$n"
- case _ => "?"
- }
- val lowerBoundString = lowerBound match {
- case firrtlir.Closed(l) => s"[$l"
- case firrtlir.Open(l) => s"($l"
- case firrtlir.UnknownBound => s"[?"
- }
- val upperBoundString = upperBound match {
- case firrtlir.Closed(l) => s"$l]"
- case firrtlir.Open(l) => s"$l)"
- case firrtlir.UnknownBound => s"?]"
- }
- s"""range"$lowerBoundString,$upperBoundString.$binaryPoint""""
- }
-
- val increment: Option[BigDecimal] = firrtlBinaryPoint match {
- case firrtlir.IntWidth(bp) =>
- Some(BigDecimal(math.pow(2, -bp.doubleValue)))
- case _ => None
- }
-
- /** If possible returns the lowest possible value for this Interval
- * @return
- */
- val getLowestPossibleValue: Option[BigDecimal] = {
- increment match {
- case Some(inc) =>
- lower match {
- case firrtlir.Closed(n) => Some(n)
- case firrtlir.Open(n) => Some(n + inc)
- case _ => None
- }
- case _ =>
- None
- }
- }
-
- /** If possible returns the highest possible value for this Interval
- * @return
- */
- val getHighestPossibleValue: Option[BigDecimal] = {
- increment match {
- case Some(inc) =>
- upper match {
- case firrtlir.Closed(n) => Some(n)
- case firrtlir.Open(n) => Some(n - inc)
- case _ => None
- }
- case _ =>
- None
- }
- }
-
- /** Return a Seq of the possible values for this range
- * Mostly to be used for testing
- * @return
- */
- def getPossibleValues: NumericRange[BigDecimal] = {
- (getLowestPossibleValue, getHighestPossibleValue, increment) match {
- case (Some(low), Some(high), Some(inc)) => (low to high by inc)
- case (_, _, None) =>
- throw new ChiselException(s"BinaryPoint unknown. Cannot get possible values from IntervalRange $toString")
- case _ =>
- throw new ChiselException(s"Unknown Bound. Cannot get possible values from IntervalRange $toString")
-
- }
- }
-
- override def getWidth: Width = {
- width match {
- case firrtlir.IntWidth(n) => KnownWidth(n.toInt)
- case firrtlir.UnknownWidth => UnknownWidth()
- }
- }
-
- private def doFirrtlOp(op: firrtlir.PrimOp, that: IntervalRange): IntervalRange = {
- PrimOps
- .set_primop_type(
- firrtlir
- .DoPrim(op, Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", that)), Nil, firrtlir.UnknownType)
- )
- .tpe match {
- case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point)
- case other => sys.error("BAD!")
- }
- }
-
- private def doFirrtlDynamicShift(that: UInt, isLeft: Boolean): IntervalRange = {
- val uinttpe = that.widthOption match {
- case None => firrtlir.UIntType(firrtlir.UnknownWidth)
- case Some(w) => firrtlir.UIntType(firrtlir.IntWidth(w))
- }
- val op = if (isLeft) PrimOps.Dshl else PrimOps.Dshr
- PrimOps
- .set_primop_type(
- firrtlir
- .DoPrim(op, Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", uinttpe)), Nil, firrtlir.UnknownType)
- )
- .tpe match {
- case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point)
- case other => sys.error("BAD!")
- }
- }
-
- private def doFirrtlOp(op: firrtlir.PrimOp, that: Int): IntervalRange = {
- PrimOps
- .set_primop_type(
- firrtlir.DoPrim(op, Seq(firrtlir.Reference("a", this)), Seq(BigInt(that)), firrtlir.UnknownType)
- )
- .tpe match {
- case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point)
- case other => sys.error("BAD!")
- }
- }
-
- /** Multiply this by that, here we return a fully unknown range,
- * firrtl's range inference can figure this out
- * @param that
- * @return
- */
- override def *(that: IntervalRange): IntervalRange = {
- doFirrtlOp(PrimOps.Mul, that)
- }
-
- /** Add that to this, here we return a fully unknown range,
- * firrtl's range inference can figure this out
- * @param that
- * @return
- */
- override def +&(that: IntervalRange): IntervalRange = {
- doFirrtlOp(PrimOps.Add, that)
- }
-
- /** Subtract that from this, here we return a fully unknown range,
- * firrtl's range inference can figure this out
- * @param that
- * @return
- */
- override def -&(that: IntervalRange): IntervalRange = {
- doFirrtlOp(PrimOps.Sub, that)
- }
-
- private def adjustBoundValue(value: BigDecimal, binaryPointValue: Int): BigDecimal = {
- if (binaryPointValue >= 0) {
- val maskFactor = BigDecimal(1 << binaryPointValue)
- val a = (value * maskFactor)
- val b = a.setScale(0, RoundingMode.DOWN)
- val c = b / maskFactor
- c
- } else {
- value
- }
- }
-
- private def adjustBound(bound: firrtlir.Bound, binaryPoint: BinaryPoint): firrtlir.Bound = {
- binaryPoint match {
- case KnownBinaryPoint(binaryPointValue) =>
- bound match {
- case firrtlir.Open(value) => firrtlir.Open(adjustBoundValue(value, binaryPointValue))
- case firrtlir.Closed(value) => firrtlir.Closed(adjustBoundValue(value, binaryPointValue))
- case _ => bound
- }
- case _ => firrtlir.UnknownBound
- }
- }
-
- /** Creates a new range with the increased precision
- *
- * @param newBinaryPoint
- * @return
- */
- def incPrecision(newBinaryPoint: BinaryPoint): IntervalRange = {
- newBinaryPoint match {
- case KnownBinaryPoint(that) =>
- doFirrtlOp(PrimOps.IncP, that)
- case _ =>
- throwException(s"$this.incPrecision(newBinaryPoint = $newBinaryPoint) error, newBinaryPoint must be know")
- }
- }
-
- /** Creates a new range with the decreased precision
- *
- * @param newBinaryPoint
- * @return
- */
- def decPrecision(newBinaryPoint: BinaryPoint): IntervalRange = {
- newBinaryPoint match {
- case KnownBinaryPoint(that) =>
- doFirrtlOp(PrimOps.DecP, that)
- case _ =>
- throwException(s"$this.decPrecision(newBinaryPoint = $newBinaryPoint) error, newBinaryPoint must be know")
- }
- }
-
- /** Creates a new range with the given binary point, adjusting precision
- * on bounds as necessary
- *
- * @param newBinaryPoint
- * @return
- */
- def setPrecision(newBinaryPoint: BinaryPoint): IntervalRange = {
- newBinaryPoint match {
- case KnownBinaryPoint(that) =>
- doFirrtlOp(PrimOps.SetP, that)
- case _ =>
- throwException(s"$this.setPrecision(newBinaryPoint = $newBinaryPoint) error, newBinaryPoint must be know")
- }
- }
-
- /** Shift this range left, i.e. shifts the min and max by the specified amount
- * @param that
- * @return
- */
- override def <<(that: Int): IntervalRange = {
- doFirrtlOp(PrimOps.Shl, that)
- }
-
- /** Shift this range left, i.e. shifts the min and max by the known width
- * @param that
- * @return
- */
- override def <<(that: KnownWidth): IntervalRange = {
- <<(that.value)
- }
-
- /** Shift this range left, i.e. shifts the min and max by value
- * @param that
- * @return
- */
- def <<(that: UInt): IntervalRange = {
- doFirrtlDynamicShift(that, isLeft = true)
- }
-
- /** Shift this range right, i.e. shifts the min and max by the specified amount
- * @param that
- * @return
- */
- override def >>(that: Int): IntervalRange = {
- doFirrtlOp(PrimOps.Shr, that)
- }
-
- /** Shift this range right, i.e. shifts the min and max by the known width
- * @param that
- * @return
- */
- override def >>(that: KnownWidth): IntervalRange = {
- >>(that.value)
- }
-
- /** Shift this range right, i.e. shifts the min and max by value
- * @param that
- * @return
- */
- def >>(that: UInt): IntervalRange = {
- doFirrtlDynamicShift(that, isLeft = false)
- }
-
- /**
- * Squeeze returns the intersection of the ranges this interval and that Interval
- * @param that
- * @return
- */
- def squeeze(that: IntervalRange): IntervalRange = {
- doFirrtlOp(PrimOps.Squeeze, that)
- }
-
- /**
- * Wrap the value of this [[Interval]] into the range of a different Interval with a presumably smaller range.
- * @param that
- * @return
- */
- def wrap(that: IntervalRange): IntervalRange = {
- doFirrtlOp(PrimOps.Wrap, that)
- }
-
- /**
- * Clip the value of this [[Interval]] into the range of a different Interval with a presumably smaller range.
- * @param that
- * @return
- */
- def clip(that: IntervalRange): IntervalRange = {
- doFirrtlOp(PrimOps.Clip, that)
- }
-
- /** merges the ranges of this and that, basically takes lowest low, highest high and biggest bp
- * set unknown if any of this or that's value of above is unknown
- * Like an union but will slurp up points in between the two ranges that were part of neither
- * @param that
- * @return
- */
- override def merge(that: IntervalRange): IntervalRange = {
- val lowest = (this.getLowestPossibleValue, that.getLowestPossibleValue) match {
- case (Some(l1), Some(l2)) =>
- if (l1 < l2) { this.lower }
- else { that.lower }
- case _ =>
- firrtlir.UnknownBound
- }
- val highest = (this.getHighestPossibleValue, that.getHighestPossibleValue) match {
- case (Some(l1), Some(l2)) =>
- if (l1 >= l2) { this.lower }
- else { that.lower }
- case _ =>
- firrtlir.UnknownBound
- }
- val newBinaryPoint = (this.firrtlBinaryPoint, that.firrtlBinaryPoint) match {
- case (firrtlir.IntWidth(b1), firrtlir.IntWidth(b2)) =>
- if (b1 > b2) { firrtlir.IntWidth(b1) }
- else { firrtlir.IntWidth(b2) }
- case _ =>
- firrtlir.UnknownWidth
- }
- IntervalRange(lowest, highest, newBinaryPoint)
- }
-
- def binaryPoint: BinaryPoint = {
- firrtlBinaryPoint match {
- case firrtlir.IntWidth(n) =>
- assert(n < Int.MaxValue, s"binary point value $n is out of range")
- KnownBinaryPoint(n.toInt)
- case _ => UnknownBinaryPoint
- }
- }
-}
-
abstract class Command {
def sourceInfo: SourceInfo
}
@@ -858,14 +361,6 @@ abstract class Component extends Arg {
}
@nowarn("msg=class Port") // delete when Port becomes private
case class DefModule(id: RawModule, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component
-@nowarn("msg=class Port") // delete when Port becomes private
-case class DefBlackBox(
- id: BaseBlackBox,
- name: String,
- ports: Seq[Port],
- topDir: SpecifiedDirection,
- params: Map[String, Param])
- extends Component
case class Circuit(
name: String,
diff --git a/core/src/main/scala/chisel3/package.scala b/core/src/main/scala/chisel3/package.scala
index afffad1c..d30a5c83 100644
--- a/core/src/main/scala/chisel3/package.scala
+++ b/core/src/main/scala/chisel3/package.scala
@@ -152,31 +152,6 @@ package object chisel3 {
def asBool(dummy: Int*): Bool = asBool
}
- // Fixed Point is experimental for now, but we alias the implicit conversion classes here
- // to minimize disruption with existing code.
- 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)
- extends experimental.Interval.Implicits.fromIntToLiteralInterval(int)
-
- implicit class fromLongToLiteralInterval(long: Long)
- extends experimental.Interval.Implicits.fromLongToLiteralInterval(long)
-
- implicit class fromBigIntToLiteralInterval(bigInt: BigInt)
- extends experimental.Interval.Implicits.fromBigIntToLiteralInterval(bigInt)
-
- implicit class fromDoubleToLiteralInterval(double: Double)
- extends experimental.Interval.Implicits.fromDoubleToLiteralInterval(double)
-
- implicit class fromBigDecimalToLiteralInterval(bigDecimal: BigDecimal)
- extends experimental.Interval.Implicits.fromBigDecimalToLiteralInterval(bigDecimal)
-
implicit class fromIntToWidth(int: Int) {
def W: Width = Width(int)
}
@@ -367,7 +342,7 @@ package object chisel3 {
"duplicated with DataMirror.fullModulePorts, this returns an internal API, will be removed in Chisel 3.6",
"Chisel 3.5"
)
- def getModulePorts(m: Module): Seq[Port] = m.getPorts
+ def getModulePorts(m: Module): Seq[Port] = Seq.empty
class BindingException(message: String) extends ChiselException(message)