summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala6
-rw-r--r--src/main/scala/chisel3/aop/AspectLibrary.scala53
-rw-r--r--src/main/scala/chisel3/aop/Select.scala614
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectStatement.scala26
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala108
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingTransform.scala46
-rw-r--r--src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala26
-rw-r--r--src/main/scala/chisel3/compatibility.scala693
-rw-r--r--src/main/scala/chisel3/experimental/conversions/package.scala240
-rw-r--r--src/main/scala/chisel3/stage/ChiselPhase.scala1
-rw-r--r--src/main/scala/chisel3/stage/ChiselStage.scala5
-rw-r--r--src/main/scala/chisel3/stage/phases/AspectPhase.scala36
-rw-r--r--src/main/scala/chisel3/stage/phases/Emitter.scala1
-rw-r--r--src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala23
-rw-r--r--src/main/scala/chisel3/util/BlackBoxUtils.scala89
-rw-r--r--src/main/scala/chisel3/util/ExtModuleUtils.scala63
-rw-r--r--src/main/scala/chisel3/util/Math.scala11
52 files changed, 74 insertions, 7383 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)
diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala
index dd9f24fb..c0efb4ed 100644
--- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala
+++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala
@@ -88,7 +88,6 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments)
tq"chisel3.VerificationStatement"
)
private val shouldMatchModule: Type => Boolean = shouldMatchGen(tq"chisel3.experimental.BaseModule")
- private val shouldMatchInstance: Type => Boolean = shouldMatchGen(tq"chisel3.experimental.hierarchy.Instance[_]")
private val shouldMatchChiselPrefixed: Type => Boolean =
shouldMatchGen(
tq"chisel3.experimental.AffectsChiselPrefix"
@@ -215,11 +214,6 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments)
val newRHS = transform(rhs)
val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)"
treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named))
- } else if (shouldMatchInstance(tpe)) {
- val str = stringFromTermName(name)
- val newRHS = transform(rhs)
- val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)"
- treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named))
} else {
// Otherwise, continue
super.transform(tree)
diff --git a/src/main/scala/chisel3/aop/AspectLibrary.scala b/src/main/scala/chisel3/aop/AspectLibrary.scala
deleted file mode 100644
index 04ac2384..00000000
--- a/src/main/scala/chisel3/aop/AspectLibrary.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3.RawModule
-import firrtl.options.{OptionsException, RegisteredLibrary, ShellOption}
-
-/** Enables adding aspects to a design from the commandline, e.g.
- * sbt> runMain chisel3.stage.ChiselMain --module <module> --with-aspect <aspect>
- */
-final class AspectLibrary() extends RegisteredLibrary {
- val name = "AspectLibrary"
-
- import scala.reflect.runtime.universe._
-
- private def apply(aspectName: String): Aspect[RawModule] = {
- try {
- // If a regular class, instantiate, otherwise try as a singleton object
- try {
- val x = Class.forName(aspectName).asInstanceOf[Class[_ <: Aspect[RawModule]]]
- x.newInstance()
- } catch {
- case e: InstantiationException =>
- val rm = runtimeMirror(getClass.getClassLoader)
- val x = rm.staticModule(aspectName)
- try {
- rm.reflectModule(x).instance.asInstanceOf[Aspect[RawModule]]
- } catch {
- case _: Exception => throw e
- }
- }
- } catch {
- case e: ClassNotFoundException =>
- throw new OptionsException(s"Unable to locate aspect '$aspectName'! (Did you misspell it?)", e)
- case e: InstantiationException =>
- throw new OptionsException(
- s"Unable to create instance of aspect '$aspectName'! (Does this class take parameters?)",
- e
- )
- }
- }
-
- val options = Seq(
- new ShellOption[String](
- longOption = "with-aspect",
- toAnnotationSeq = {
- case aspectName: String => Seq(apply(aspectName))
- },
- helpText = "The name/class of an aspect to compile with (must be a class/object without arguments!)",
- helpValueName = Some("<package>.<aspect>")
- )
- )
-}
diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala
deleted file mode 100644
index 738d6f31..00000000
--- a/src/main/scala/chisel3/aop/Select.scala
+++ /dev/null
@@ -1,614 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3._
-import chisel3.internal.{HasId}
-import chisel3.experimental.BaseModule
-import chisel3.experimental.FixedPoint
-import chisel3.internal.firrtl.{Definition => DefinitionIR, _}
-import chisel3.experimental.hierarchy._
-import chisel3.internal.PseudoModule
-import chisel3.internal.BaseModule.ModuleClone
-import firrtl.annotations.ReferenceTarget
-import scala.reflect.runtime.universe.TypeTag
-
-import scala.collection.mutable
-import chisel3.internal.naming.chiselName
-
-/** Use to select Chisel components in a module, after that module has been constructed
- * Useful for adding additional Chisel annotations or for use within an [[Aspect]]
- */
-object Select {
-
- /** Return just leaf components of expanded node
- *
- * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies are not included
- */
- def getLeafs(d: Data): Seq[Data] = d match {
- case r: Record => r.elementsIterator.flatMap(getLeafs).toSeq
- case v: Vec[_] => v.getElements.flatMap(getLeafs)
- case other => Seq(other)
- }
-
- /** Return all expanded components, including intermediate aggregate nodes
- *
- * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies ARE included
- */
- def getIntermediateAndLeafs(d: Data): Seq[Data] = d match {
- case r: Record => r +: r.elementsIterator.flatMap(getIntermediateAndLeafs).toSeq
- case v: Vec[_] => v +: v.getElements.flatMap(getIntermediateAndLeafs)
- case other => Seq(other)
- }
-
- /** Selects all instances/modules directly instantiated within given definition
- *
- * @param parent
- */
- def instancesIn(parent: Hierarchy[BaseModule]): Seq[Instance[BaseModule]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent.proto._component.get match {
- case d: DefModule =>
- d.commands.collect {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
- case other: BaseModule =>
- parent._lookup { x => other }
- }
- }
- case other => Nil
- }
- }
-
- /** Selects all Instances of instances/modules directly instantiated within given module, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. instancesOf[List[Int]] would return List[String].
- *
- * @param parent hierarchy which instantiates the returned Definitions
- */
- def instancesOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent.proto._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
- if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
- case other: BaseModule =>
- val i = parent._lookup { x => other }
- if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
- }
- case other => None
- }
- case other => Nil
- }
- }
-
- /** Selects all Instances directly and indirectly instantiated within given root hierarchy, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. allInstancesOf[List[Int]] would return List[String].
- *
- * @param root top of the hierarchy to search for instances/modules of given type
- */
- def allInstancesOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = {
- val soFar = if (root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil
- val allLocalInstances = instancesIn(root)
- soFar ++ (allLocalInstances.flatMap(allInstancesOf[T]))
- }
-
- /** Selects the Definitions of all instances/modules directly instantiated within given module
- *
- * @param parent
- */
- def definitionsIn(parent: Hierarchy[BaseModule]): Seq[Definition[BaseModule]] = {
- type DefType = Definition[BaseModule]
- implicit val mg = new chisel3.internal.MacroGenerated {}
- check(parent)
- val defs = parent.proto._component.get match {
- case d: DefModule =>
- d.commands.collect {
- case i: DefInstance =>
- i.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] }
- case other: BaseModule =>
- parent._lookup { x => other.toDefinition }
- }
- }
- case other => Nil
- }
- val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
- case ((set, list), definition: Definition[BaseModule]) =>
- if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
- }
- defList.reverse
- }
-
- /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. definitionsOf[List[Int]] would return List[String].
- *
- * @param parent hierarchy which instantiates the returned Definitions
- */
- def definitionsOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- type DefType = Definition[T]
- val defs = parent.proto._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] }
- if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
- case other: BaseModule =>
- val d = parent._lookup { x => other.toDefinition }
- if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
- }
- case other => None
- }
- }
- val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
- case ((set, list), definition: Definition[T]) =>
- if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
- }
- defList.reverse
- }
-
- /** Selects all Definition's directly and indirectly instantiated within given root hierarchy, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class, i.e.
- * a class defined within another class.
- * @note IMPORTANT: this function ignores type parameters. E.g. allDefinitionsOf[List[Int]] would return List[String].
- *
- * @param root top of the hierarchy to search for definitions of given type
- */
- def allDefinitionsOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = {
- type DefType = Definition[T]
- val allDefSet = mutable.HashSet[Definition[BaseModule]]()
- val defSet = mutable.HashSet[DefType]()
- val defList = mutable.ArrayBuffer[DefType]()
- def rec(hier: Definition[BaseModule]): Unit = {
- if (hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) {
- defSet += hier.asInstanceOf[DefType]
- defList += hier.asInstanceOf[DefType]
- }
- allDefSet += hier
- val allDefs = definitionsIn(hier)
- allDefs.collect {
- case d if !allDefSet.contains(d) => rec(d)
- }
- }
- rec(root.toDefinition)
- defList.toList
- }
-
- /** Collects all components selected by collector within module and all children modules it instantiates
- * directly or indirectly
- * Accepts a collector function, rather than a collector partial function (see [[collectDeep]])
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
- *
- * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
- * @param collector Collector function to pick, given a module, which components to collect
- * @param tag Required for generics to work, should ignore this
- * @tparam T Type of the component that will be collected
- */
- def getDeep[T](module: BaseModule)(collector: BaseModule => Seq[T]): Seq[T] = {
- check(module)
- val myItems = collector(module)
- val deepChildrenItems = instances(module).flatMap { i =>
- getDeep(i)(collector)
- }
- myItems ++ deepChildrenItems
- }
-
- /** Collects all components selected by collector within module and all children modules it instantiates
- * directly or indirectly
- * Accepts a collector partial function, rather than a collector function (see [[getDeep]])
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
- *
- * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
- * @param collector Collector partial function to pick, given a module, which components to collect
- * @param tag Required for generics to work, should ignore this
- * @tparam T Type of the component that will be collected
- */
- def collectDeep[T](module: BaseModule)(collector: PartialFunction[BaseModule, T]): Iterable[T] = {
- check(module)
- val myItems = collector.lift(module)
- val deepChildrenItems = instances(module).flatMap { i =>
- collectDeep(i)(collector)
- }
- myItems ++ deepChildrenItems
- }
-
- /** Selects all modules directly instantiated within given module
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use instancesIn or definitionsIn.
- *
- * @param module
- */
- def instances(module: BaseModule): Seq[BaseModule] = {
- check(module)
- module._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case i: DefInstance =>
- i.id match {
- case m: ModuleClone[_] if !m._madeFromDefinition => None
- case _: PseudoModule =>
- throw new Exception(
- "instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!"
- )
- case other => Some(other)
- }
- case _ => None
- }
- case other => Nil
- }
- }
-
- /** Selects all registers directly instantiated within given module
- * @param module
- */
- def registers(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefReg => r.id
- case r: DefRegInit => r.id
- }
- }
-
- /** Selects all ios on a given module
- * @param module
- */
- def ios(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].ports.map(_.id)
- }
-
- /** Selects all ios directly on a given Instance or Definition of a module
- * @param parent the Definition or Instance to get the IOs of
- */
- def ios[T <: BaseModule](parent: Hierarchy[T]): Seq[Data] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent._lookup { x => ios(parent.proto) }
- }
-
- /** Selects all SyncReadMems directly contained within given module
- * @param module
- */
- def syncReadMems(module: BaseModule): Seq[SyncReadMem[_]] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefSeqMemory => r.id.asInstanceOf[SyncReadMem[_]]
- }
- }
-
- /** Selects all Mems directly contained within given module
- * @param module
- */
- def mems(module: BaseModule): Seq[Mem[_]] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemory => r.id.asInstanceOf[Mem[_]]
- }
- }
-
- /** Selects all arithmetic or logical operators directly instantiated within given module
- * @param module
- */
- def ops(module: BaseModule): Seq[(String, Data)] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case d: DefPrim[_] => (d.op.name, d.id)
- }
- }
-
- /** Selects a kind of arithmetic or logical operator directly instantiated within given module
- * The kind of operators are contained in [[chisel3.internal.firrtl.PrimOp]]
- * @param opKind the kind of operator, e.g. "mux", "add", or "bits"
- * @param module
- */
- def ops(opKind: String)(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case d: DefPrim[_] if d.op.name == opKind => d.id
- }
- }
-
- /** Selects all wires in a module
- * @param module
- */
- def wires(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefWire => r.id
- }
- }
-
- /** Selects all memory ports, including their direction and memory
- * @param module
- */
- def memPorts(module: BaseModule): Seq[(Data, MemPortDirection, MemBase[_])] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemPort[_] => (r.id, r.dir, r.source.id.asInstanceOf[MemBase[_ <: Data]])
- }
- }
-
- /** Selects all memory ports of a given direction, including their memory
- * @param dir The direction of memory ports to select
- * @param module
- */
- def memPorts(dir: MemPortDirection)(module: BaseModule): Seq[(Data, MemBase[_])] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemPort[_] if r.dir == dir => (r.id, r.source.id.asInstanceOf[MemBase[_ <: Data]])
- }
- }
-
- /** Selects all components who have been set to be invalid, even if they are later connected to
- * @param module
- */
- def invalids(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case DefInvalid(_, arg) => getData(arg)
- }
- }
-
- /** Selects all components who are attached to a given signal, within a module
- * @param module
- */
- def attachedTo(module: BaseModule)(signal: Data): Set[Data] = {
- check(module)
- module._component.get
- .asInstanceOf[DefModule]
- .commands
- .collect {
- case Attach(_, seq) if seq.contains(signal) => seq
- }
- .flatMap { seq => seq.map(_.id.asInstanceOf[Data]) }
- .toSet
- }
-
- /** Selects all connections to a signal or its parent signal(s) (if the signal is an element of an aggregate signal)
- * The when predicates surrounding each connection are included in the returned values
- *
- * E.g. if signal = io.foo.bar, connectionsTo will return all connections to io, io.foo, and io.bar
- * @param module
- * @param signal
- */
- def connectionsTo(module: BaseModule)(signal: Data): Seq[PredicatedConnect] = {
- check(module)
- val sensitivitySignals = getIntermediateAndLeafs(signal).toSet
- val predicatedConnects = mutable.ArrayBuffer[PredicatedConnect]()
- val isPort = module._component.get
- .asInstanceOf[DefModule]
- .ports
- .flatMap { p => getIntermediateAndLeafs(p.id) }
- .contains(signal)
- var prePredicates: Seq[Predicate] = Nil
- var seenDef = isPort
- searchWhens(
- module,
- (cmd: Command, preds) => {
- cmd match {
- case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] =>
- val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data])
- if (x.contains(signal)) prePredicates = preds
- case Connect(_, loc @ Node(d: Data), exp) =>
- val effected = getEffected(loc).toSet
- if (sensitivitySignals.intersect(effected).nonEmpty) {
- val expData = getData(exp)
- prePredicates.reverse
- .zip(preds.reverse)
- .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
- predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = false)
- }
- case BulkConnect(_, loc @ Node(d: Data), exp) =>
- val effected = getEffected(loc).toSet
- if (sensitivitySignals.intersect(effected).nonEmpty) {
- val expData = getData(exp)
- prePredicates.reverse
- .zip(preds.reverse)
- .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
- predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = true)
- }
- case other =>
- }
- }
- )
- predicatedConnects.toSeq
- }
-
- /** Selects all stop statements, and includes the predicates surrounding the stop statement
- *
- * @param module
- */
- def stops(module: BaseModule): Seq[Stop] = {
- val stops = mutable.ArrayBuffer[Stop]()
- searchWhens(
- module,
- (cmd: Command, preds: Seq[Predicate]) => {
- cmd match {
- case chisel3.internal.firrtl.Stop(_, _, clock, ret) =>
- stops += Stop(preds, ret, getId(clock).asInstanceOf[Clock])
- case other =>
- }
- }
- )
- stops.toSeq
- }
-
- /** Selects all printf statements, and includes the predicates surrounding the printf statement
- *
- * @param module
- */
- def printfs(module: BaseModule): Seq[Printf] = {
- val printfs = mutable.ArrayBuffer[Printf]()
- searchWhens(
- module,
- (cmd: Command, preds: Seq[Predicate]) => {
- cmd match {
- case chisel3.internal.firrtl.Printf(id, _, clock, pable) =>
- printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock])
- case other =>
- }
- }
- )
- printfs.toSeq
- }
-
- // Checks that a module has finished its construction
- private def check(module: BaseModule): Unit = {
- require(module.isClosed, "Can't use Selector on modules that have not finished construction!")
- require(module._component.isDefined, "Can't use Selector on modules that don't have components!")
- }
- private def check(hierarchy: Hierarchy[BaseModule]): Unit = check(hierarchy.proto)
-
- // Given a loc, return all subcomponents of id that could be assigned to in connect
- private def getEffected(a: Arg): Seq[Data] = a match {
- case Node(id: Data) => getIntermediateAndLeafs(id)
- case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name))
- case Index(imm, value) => getEffected(imm)
- }
-
- // Given an arg, return the corresponding id. Don't use on a loc of a connect.
- private def getId(a: Arg): HasId = a match {
- case Node(id) => id
- case l: ULit => l.num.U(l.w)
- case l: SLit => l.num.S(l.w)
- case l: FPLit => FixedPoint(l.num, l.w, l.binaryPoint)
- case other =>
- sys.error(s"Something went horribly wrong! I was expecting ${other} to be a lit or a node!")
- }
-
- private def getData(a: Arg): Data = a match {
- case Node(data: Data) => data
- case other =>
- sys.error(s"Something went horribly wrong! I was expecting ${other} to be Data!")
- }
-
- // Given an id, either get its name or its value, if its a lit
- private def getName(i: HasId): String = try {
- i.toTarget match {
- case r: ReferenceTarget =>
- val str = r.serialize
- str.splitAt(str.indexOf('>'))._2.drop(1)
- }
- } catch {
- case e: ChiselException =>
- i.getOptionRef.get match {
- case l: LitArg => l.num.intValue.toString
- }
- }
-
- // Collects when predicates as it searches through a module, then applying processCommand to non-when related commands
- private def searchWhens(module: BaseModule, processCommand: (Command, Seq[Predicate]) => Unit) = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.foldLeft((Seq.empty[Predicate], Option.empty[Predicate])) {
- (blah, cmd) =>
- (blah, cmd) match {
- case ((preds, o), cmd) =>
- cmd match {
- case WhenBegin(_, Node(pred: Bool)) => (When(pred) +: preds, None)
- case WhenBegin(_, l: LitArg) if l.num == BigInt(1) => (When(true.B) +: preds, None)
- case WhenBegin(_, l: LitArg) if l.num == BigInt(0) => (When(false.B) +: preds, None)
- case other: WhenBegin =>
- sys.error(s"Something went horribly wrong! I was expecting ${other.pred} to be a lit or a bool!")
- case _: WhenEnd => (preds.tail, Some(preds.head))
- case AltBegin(_) if o.isDefined => (o.get.not +: preds, o)
- case _: AltBegin =>
- sys.error(s"Something went horribly wrong! I was expecting ${o} to be nonEmpty!")
- case OtherwiseEnd(_, _) => (preds.tail, None)
- case other =>
- processCommand(cmd, preds)
- (preds, o)
- }
- }
- }
- }
-
- trait Serializeable {
- def serialize: String
- }
-
- /** Used to indicates a when's predicate (or its otherwise predicate)
- */
- trait Predicate extends Serializeable {
- val bool: Bool
- def not: Predicate
- }
-
- /** Used to represent [[chisel3.when]] predicate
- *
- * @param bool the when predicate
- */
- case class When(bool: Bool) extends Predicate {
- def not: WhenNot = WhenNot(bool)
- def serialize: String = s"${getName(bool)}"
- }
-
- /** Used to represent the `otherwise` predicate of a [[chisel3.when]]
- *
- * @param bool the when predicate corresponding to this otherwise predicate
- */
- case class WhenNot(bool: Bool) extends Predicate {
- def not: When = When(bool)
- def serialize: String = s"!${getName(bool)}"
- }
-
- /** Used to represent a connection or bulk connection
- *
- * Additionally contains the sequence of when predicates seen when the connection is declared
- *
- * @param preds
- * @param loc
- * @param exp
- * @param isBulk
- */
- case class PredicatedConnect(preds: Seq[Predicate], loc: Data, exp: Data, isBulk: Boolean) extends Serializeable {
- def serialize: String = {
- val moduleTarget = loc.toTarget.moduleTarget.serialize
- s"$moduleTarget: when(${preds.map(_.serialize).mkString(" & ")}): ${getName(loc)} ${if (isBulk) "<>" else ":="} ${getName(exp)}"
- }
- }
-
- /** Used to represent a [[chisel3.stop]]
- *
- * @param preds
- * @param ret
- * @param clock
- */
- case class Stop(preds: Seq[Predicate], ret: Int, clock: Clock) extends Serializeable {
- def serialize: String = {
- s"stop when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $ret"
- }
- }
-
- /** Used to represent a [[chisel3.printf]]
- *
- * @param preds
- * @param pable
- * @param clock
- */
- case class Printf(id: printf.Printf, preds: Seq[Predicate], pable: Printable, clock: Clock) extends Serializeable {
- def serialize: String = {
- s"printf when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $pable"
- }
- }
-}
diff --git a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala b/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
deleted file mode 100644
index dbe1fd7b..00000000
--- a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.injecting
-
-import chisel3.stage.phases.AspectPhase
-import firrtl.annotations.{Annotation, ModuleTarget, NoTargetAnnotation, SingleTargetAnnotation}
-
-/** Contains all information needed to inject statements into a module
- *
- * Generated when a [[InjectingAspect]] is consumed by a [[AspectPhase]]
- * Consumed by [[InjectingTransform]]
- *
- * @param module Module to inject code into at the end of the module
- * @param s Statements to inject
- * @param modules Additional modules that may be instantiated by s
- * @param annotations Additional annotations that should be passed down compiler
- */
-case class InjectStatement(
- module: ModuleTarget,
- s: firrtl.ir.Statement,
- modules: Seq[firrtl.ir.DefModule],
- annotations: Seq[Annotation])
- extends SingleTargetAnnotation[ModuleTarget] {
- val target: ModuleTarget = module
- override def duplicate(n: ModuleTarget): Annotation = this.copy(module = n)
-}
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
deleted file mode 100644
index ecce19e1..00000000
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.injecting
-
-import chisel3.{withClockAndReset, Module, ModuleAspect, RawModule}
-import chisel3.aop._
-import chisel3.internal.{Builder, DynamicContext}
-import chisel3.internal.firrtl.DefModule
-import chisel3.stage.{ChiselOptions, DesignAnnotation}
-import firrtl.annotations.ModuleTarget
-import firrtl.stage.RunFirrtlTransformAnnotation
-import firrtl.options.Viewer.view
-import firrtl.{ir, _}
-
-import scala.collection.mutable
-
-/** Aspect to inject Chisel code into a module of type M
- *
- * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
- * @param injection Function to generate Chisel hardware that will be injected to the end of module m
- * Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
- * @tparam T Type of top-level module
- * @tparam M Type of root module (join point)
- */
-case class InjectingAspect[T <: RawModule, M <: RawModule](
- selectRoots: T => Iterable[M],
- injection: M => Unit)
- extends InjectorAspect[T, M](
- selectRoots,
- injection
- )
-
-/** Extend to inject Chisel code into a module of type M
- *
- * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
- * @param injection Function to generate Chisel hardware that will be injected to the end of module m
- * Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
- * @tparam T Type of top-level module
- * @tparam M Type of root module (join point)
- */
-abstract class InjectorAspect[T <: RawModule, M <: RawModule](
- selectRoots: T => Iterable[M],
- injection: M => Unit)
- extends Aspect[T] {
- final def toAnnotation(top: T): AnnotationSeq = {
- val moduleNames =
- Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map { i => i.toTarget.module }.toSeq
- toAnnotation(selectRoots(top), top.name, moduleNames)
- }
-
- /** Returns annotations which contain all injection logic
- *
- * @param modules The modules to inject into
- * @param circuit Top level circuit
- * @param moduleNames The names of all existing modules in the original circuit, to avoid name collisions
- * @return
- */
- final def toAnnotation(modules: Iterable[M], circuit: String, moduleNames: Seq[String]): AnnotationSeq = {
- RunFirrtlTransformAnnotation(new InjectingTransform) +: modules.map { module =>
- val chiselOptions = view[ChiselOptions](annotationsInAspect)
- val dynamicContext =
- new DynamicContext(
- annotationsInAspect,
- chiselOptions.throwOnFirstError,
- chiselOptions.warnReflectiveNaming,
- chiselOptions.warningsAsErrors
- )
- // Add existing module names into the namespace. If injection logic instantiates new modules
- // which would share the same name, they will get uniquified accordingly
- moduleNames.foreach { n =>
- dynamicContext.globalNamespace.name(n)
- }
-
- val (chiselIR, _) = Builder.build(
- Module(new ModuleAspect(module) {
- module match {
- case x: Module => withClockAndReset(x.clock, x.reset) { injection(module) }
- case x: RawModule => injection(module)
- }
- }),
- dynamicContext
- )
-
- val comps = chiselIR.components.map {
- case x: DefModule if x.name == module.name => x.copy(id = module)
- case other => other
- }
-
- val annotations = chiselIR.annotations.map(_.toFirrtl).filterNot { a => a.isInstanceOf[DesignAnnotation[_]] }
-
- /** Statements to be injected via aspect. */
- val stmts = mutable.ArrayBuffer[ir.Statement]()
-
- /** Modules to be injected via aspect. */
- val modules = Aspect.getFirrtl(chiselIR.copy(components = comps)).modules.flatMap {
- // for "container" modules, inject their statements
- case m: firrtl.ir.Module if m.name == module.name =>
- stmts += m.body
- Nil
- // for modules to be injected
- case other: firrtl.ir.DefModule =>
- Seq(other)
- }
-
- InjectStatement(ModuleTarget(circuit, module.name), ir.Block(stmts.toSeq), modules, annotations)
- }.toSeq
- }
-}
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala b/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
deleted file mode 100644
index 8a0b6ecb..00000000
--- a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.injecting
-
-import firrtl.{ir, ChirrtlForm, CircuitForm, CircuitState, Transform}
-
-import scala.collection.mutable
-
-/** Appends statements contained in [[InjectStatement]] annotations to the end of their corresponding modules
- *
- * Implemented with Chisel Aspects and the [[chisel3.aop.injecting]] library
- */
-class InjectingTransform extends Transform {
- override def inputForm: CircuitForm = ChirrtlForm
- override def outputForm: CircuitForm = ChirrtlForm
-
- override def execute(state: CircuitState): CircuitState = {
-
- val addStmtMap = mutable.HashMap[String, Seq[ir.Statement]]()
- val addModules = mutable.ArrayBuffer[ir.DefModule]()
-
- // Populate addStmtMap and addModules, return annotations in InjectStatements, and omit InjectStatement annotation
- val newAnnotations = state.annotations.flatMap {
- case InjectStatement(mt, s, addedModules, annotations) =>
- addModules ++= addedModules
- addStmtMap(mt.module) = s +: addStmtMap.getOrElse(mt.module, Nil)
- annotations
- case other => Seq(other)
- }
-
- // Append all statements to end of corresponding modules
- val newModules = state.circuit.modules.map { m: ir.DefModule =>
- m match {
- case m: ir.Module if addStmtMap.contains(m.name) =>
- m.copy(body = ir.Block(m.body +: addStmtMap(m.name)))
- case m: _root_.firrtl.ir.ExtModule if addStmtMap.contains(m.name) =>
- ir.Module(m.info, m.name, m.ports, ir.Block(addStmtMap(m.name)))
- case other: ir.DefModule => other
- }
- }
-
- // Return updated circuit and annotations
- val newCircuit = state.circuit.copy(modules = newModules ++ addModules)
- state.copy(annotations = newAnnotations, circuit = newCircuit)
- }
-}
diff --git a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala b/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
deleted file mode 100644
index 1340f253..00000000
--- a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.inspecting
-
-import chisel3.RawModule
-import chisel3.aop.Aspect
-import firrtl.AnnotationSeq
-
-/** Use for inspecting an elaborated design and printing out results
- *
- * @param inspect Given top-level design, print things and return nothing
- * @tparam T Type of top-level module
- */
-case class InspectingAspect[T <: RawModule](inspect: T => Unit) extends InspectorAspect[T](inspect)
-
-/** Extend to make custom inspections of an elaborated design and printing out results
- *
- * @param inspect Given top-level design, print things and return nothing
- * @tparam T Type of top-level module
- */
-abstract class InspectorAspect[T <: RawModule](inspect: T => Unit) extends Aspect[T] {
- override def toAnnotation(top: T): AnnotationSeq = {
- inspect(top)
- Nil
- }
-}
diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala
deleted file mode 100644
index d140725f..00000000
--- a/src/main/scala/chisel3/compatibility.scala
+++ /dev/null
@@ -1,693 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-/** The Chisel compatibility package allows legacy users to continue using the `Chisel` (capital C) package name
- * while moving to the more standard package naming convention `chisel3` (lowercase c).
- */
-import chisel3._ // required for implicit conversions.
-import chisel3.util.random.FibonacciLFSR
-import chisel3.stage.{phases, ChiselCircuitAnnotation, ChiselOutputFileAnnotation, ChiselStage}
-
-package object Chisel {
- import chisel3.internal.firrtl.Width
-
- import scala.language.experimental.macros
- import scala.annotation.StaticAnnotation
- import scala.annotation.compileTimeOnly
- import scala.language.implicitConversions
-
- implicit val defaultCompileOptions = chisel3.ExplicitCompileOptions.NotStrict
-
- abstract class Direction
- case object INPUT extends Direction
- case object OUTPUT extends Direction
- case object NODIR extends Direction
-
- val Input = chisel3.Input
- val Output = chisel3.Output
-
- object Flipped {
- def apply[T <: Data](target: T): T = chisel3.Flipped[T](target)
- }
-
- implicit class AddDirectionToData[T <: Data](target: T) {
- def asInput: T = Input(target)
- def asOutput: T = Output(target)
- def flip: T = Flipped(target)
-
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- def flip(dummy: Int*): T = flip
- }
-
- implicit class AddDirMethodToData[T <: Data](target: T) {
- import chisel3.ActualDirection
- import chisel3.experimental.DataMirror
- import chisel3.internal.requireIsHardware
-
- def dir: Direction = {
- requireIsHardware(target) // This has the side effect of calling _autoWrapPorts
- target match {
- case e: Element =>
- DataMirror.directionOf(e) match {
- case ActualDirection.Output => OUTPUT
- case ActualDirection.Input => INPUT
- case _ => NODIR
- }
- case _ => NODIR
- }
- }
- }
- implicit class cloneTypeable[T <: Data](target: T) {
- import chisel3.experimental.DataMirror
- def chiselCloneType: T = {
- DataMirror.internal.chiselTypeClone(target).asInstanceOf[T]
- }
- }
-
- type ChiselException = chisel3.internal.ChiselException
-
- type Data = chisel3.Data
- object Wire extends WireFactory {
- import chisel3.CompileOptions
-
- def apply[T <: Data](dummy: Int = 0, init: T)(implicit compileOptions: CompileOptions): T =
- chisel3.WireDefault(init)
-
- def apply[T <: Data](t: T, init: T)(implicit compileOptions: CompileOptions): T =
- chisel3.WireDefault(t, init)
- }
- object Clock {
- def apply(): Clock = new Clock
-
- def apply(dir: Direction): Clock = {
- val result = apply()
- dir match {
- case INPUT => Input(result)
- case OUTPUT => Output(result)
- case _ => result
- }
- }
- }
- type Clock = chisel3.Clock
-
- // Implicit conversion to allow fromBits because it's being deprecated in chisel3
- implicit class fromBitsable[T <: Data](data: T) {
- import chisel3.CompileOptions
- import chisel3.internal.sourceinfo.SourceInfo
-
- /** Creates an new instance of this type, unpacking the input Bits into
- * structured data.
- *
- * This performs the inverse operation of toBits.
- *
- * @note does NOT assign to the object this is called on, instead creates
- * and returns a NEW object (useful in a clone-and-assign scenario)
- * @note does NOT check bit widths, may drop bits during assignment
- * @note what fromBits assigs to must have known widths
- */
- def fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- that.asTypeOf(data)
- }
- }
-
- type Aggregate = chisel3.Aggregate
- object Vec extends chisel3.VecFactory {
- import chisel3.CompileOptions
- import chisel3.internal.sourceinfo._
-
- @deprecated("Vec argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](gen: T, n: Int)(implicit compileOptions: CompileOptions): Vec[T] =
- apply(n, gen)
-
- /** Creates a new [[Vec]] of length `n` composed of the result of the given
- * function repeatedly applied.
- *
- * @param n number of elements (and the number of times the function is
- * called)
- * @param gen function that generates the [[Data]] that becomes the output
- * element
- */
- def fill[T <: Data](n: Int)(gen: => T)(implicit compileOptions: CompileOptions): Vec[T] =
- apply(Seq.fill(n)(gen))
-
- def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] =
- chisel3.VecInit(elts)
-
- def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](
- elt0: T,
- elts: T*
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Vec[T] =
- chisel3.VecInit(elt0 +: elts.toSeq)
-
- def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate
-
- /** @group SourceInfoTransformMacro */
- def do_tabulate[T <: Data](
- n: Int
- )(gen: (Int) => T
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): Vec[T] =
- chisel3.VecInit.tabulate(n)(gen)
- }
- type Vec[T <: Data] = chisel3.Vec[T]
- type VecLike[T <: Data] = chisel3.VecLike[T]
- type Record = chisel3.Record
- type Bundle = chisel3.Bundle
-
- val assert = chisel3.assert
- val stop = chisel3.stop
-
- /** This contains literal constructor factory methods that are deprecated as of Chisel3.
- */
- trait UIntFactory extends chisel3.UIntFactory {
-
- /** Create a UInt literal with inferred width. */
- def apply(n: String): UInt = n.asUInt
-
- /** Create a UInt literal with fixed width. */
- def apply(n: String, width: Int): UInt = n.asUInt(width.W)
-
- /** Create a UInt literal with specified width. */
- def apply(value: BigInt, width: Width): UInt = value.asUInt(width)
-
- /** Create a UInt literal with fixed width. */
- def apply(value: BigInt, width: Int): UInt = value.asUInt(width.W)
-
- /** Create a UInt with a specified width - compatibility with Chisel2. */
- // NOTE: This resolves UInt(width = 32)
- def apply(dir: Option[Direction] = None, width: Int): UInt = apply(width.W)
-
- /** Create a UInt literal with inferred width.- compatibility with Chisel2. */
- def apply(value: BigInt): UInt = value.asUInt
-
- /** Create a UInt with a specified direction and width - compatibility with Chisel2. */
- def apply(dir: Direction, width: Int): UInt = apply(dir, width.W)
-
- /** Create a UInt with a specified direction, but unspecified width - compatibility with Chisel2. */
- def apply(dir: Direction): UInt = apply(dir, Width())
- def apply(dir: Direction, width: Width): UInt = {
- val result = apply(width)
- dir match {
- case INPUT => Input(result)
- case OUTPUT => Output(result)
- case NODIR => result
- }
- }
-
- /** Create a UInt with a specified width */
- def width(width: Int): UInt = apply(width.W)
-
- /** Create a UInt port with specified width. */
- def width(width: Width): UInt = apply(width)
- }
-
- /** This contains literal constructor factory methods that are deprecated as of Chisel3.
- */
- trait SIntFactory extends chisel3.SIntFactory {
-
- /** Create a SInt type or port with fixed width. */
- def width(width: Int): SInt = apply(width.W)
-
- /** Create an SInt type with specified width. */
- def width(width: Width): SInt = apply(width)
-
- /** Create an SInt literal with inferred width. */
- def apply(value: BigInt): SInt = value.asSInt
-
- /** Create an SInt literal with fixed width. */
- def apply(value: BigInt, width: Int): SInt = value.asSInt(width.W)
-
- /** Create an SInt literal with specified width. */
- def apply(value: BigInt, width: Width): SInt = value.asSInt(width)
-
- def Lit(value: BigInt): SInt = value.asSInt
- def Lit(value: BigInt, width: Int): SInt = value.asSInt(width.W)
-
- /** Create a SInt with a specified width - compatibility with Chisel2. */
- def apply(dir: Option[Direction] = None, width: Int): SInt = apply(width.W)
-
- /** Create a SInt with a specified direction and width - compatibility with Chisel2. */
- def apply(dir: Direction, width: Int): SInt = apply(dir, width.W)
-
- /** Create a SInt with a specified direction, but unspecified width - compatibility with Chisel2. */
- def apply(dir: Direction): SInt = apply(dir, Width())
- def apply(dir: Direction, width: Width): SInt = {
- val result = apply(width)
- dir match {
- case INPUT => Input(result)
- case OUTPUT => Output(result)
- case NODIR => result
- }
- }
- }
-
- /** This contains literal constructor factory methods that are deprecated as of Chisel3.
- */
- trait BoolFactory extends chisel3.BoolFactory {
-
- /** Creates Bool literal.
- */
- def apply(x: Boolean): Bool = x.B
-
- /** Create a UInt with a specified direction and width - compatibility with Chisel2. */
- def apply(dir: Direction): Bool = {
- val result = apply()
- dir match {
- case INPUT => Input(result)
- case OUTPUT => Output(result)
- case NODIR => result
- }
- }
- }
-
- type Element = chisel3.Element
- type Bits = chisel3.Bits
- object Bits extends UIntFactory
- type Num[T <: Data] = chisel3.Num[T]
- type UInt = chisel3.UInt
- object UInt extends UIntFactory
- type SInt = chisel3.SInt
- object SInt extends SIntFactory
- type Bool = chisel3.Bool
- object Bool extends BoolFactory
- val Mux = chisel3.Mux
- type Reset = chisel3.Reset
-
- implicit def resetToBool(reset: Reset): Bool = reset.asBool
-
- type BlackBox = chisel3.internal.LegacyBlackBox
-
- type MemBase[T <: Data] = chisel3.MemBase[T]
-
- val Mem = chisel3.Mem
- type Mem[T <: Data] = chisel3.Mem[T]
-
- implicit class MemCompatibility(a: Mem.type) {
- import chisel3.internal.sourceinfo.UnlocatableSourceInfo
-
- def apply[T <: Data](t: T, size: BigInt)(implicit compileOptions: CompileOptions): Mem[T] =
- a.do_apply(size, t)(UnlocatableSourceInfo, compileOptions)
-
- def apply[T <: Data](t: T, size: Int)(implicit compileOptions: CompileOptions): Mem[T] =
- a.do_apply(size, t)(UnlocatableSourceInfo, compileOptions)
-
- }
-
- val SeqMem = chisel3.SyncReadMem
- type SeqMem[T <: Data] = chisel3.SyncReadMem[T]
-
- implicit class SeqMemCompatibility(a: SeqMem.type) {
- import chisel3.internal.sourceinfo.SourceInfo
-
- def apply[T <: Data](
- t: T,
- size: BigInt
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): SyncReadMem[T] =
- a.do_apply(size, t)
-
- def apply[T <: Data](
- t: T,
- size: Int
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): SyncReadMem[T] =
- a.do_apply(size, t)
- }
-
- import chisel3.CompileOptions
-
- @deprecated("Use Chisel.Module", "Chisel 3.5")
- type CompatibilityModule = chisel3.internal.LegacyModule
- val Module = chisel3.Module
- type Module = chisel3.internal.LegacyModule
-
- val printf = chisel3.printf
-
- val RegNext = chisel3.RegNext
- val RegInit = chisel3.RegInit
- object Reg {
- import chisel3.CompileOptions
- import chisel3.internal.sourceinfo.SourceInfo
-
- // Passthrough for chisel3.Reg
- // Single-element constructor to avoid issues caused by null default args in a type
- // parameterized scope.
- def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- chisel3.Reg(t)
-
- /** Creates a register with optional next and initialization values.
- *
- * @param t: data type for the register
- * @param next: new value register is to be updated with every cycle (or
- * empty to not update unless assigned to using the := operator)
- * @param init: initialization value on reset (or empty for uninitialized,
- * where the register value persists across a reset)
- *
- * @note this may result in a type error if called from a type parameterized
- * function, since the Scala compiler isn't smart enough to know that null
- * is a valid value. In those cases, you can either use the outType only Reg
- * constructor or pass in `null.asInstanceOf[T]`.
- */
- def apply[T <: Data](
- t: T = null,
- next: T = null,
- init: T = null
- )(
- implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions
- ): T = {
- if (t ne null) {
- val reg = if (init ne null) {
- RegInit(t, init)
- } else {
- chisel3.Reg(t)
- }
- if (next ne null) {
- reg := next
- }
- reg
- } else if (next ne null) {
- if (init ne null) {
- RegNext(next, init)
- } else {
- RegNext(next)
- }
- } else if (init ne null) {
- RegInit(init)
- } else {
- throwException("cannot infer type")
- }
- }
- }
-
- val when = chisel3.when
- type WhenContext = chisel3.WhenContext
-
- implicit class fromBigIntToLiteral(x: BigInt) extends chisel3.fromBigIntToLiteral(x)
- implicit class fromtIntToLiteral(x: Int) extends chisel3.fromIntToLiteral(x)
- implicit class fromtLongToLiteral(x: Long) extends chisel3.fromLongToLiteral(x)
- implicit class fromStringToLiteral(x: String) extends chisel3.fromStringToLiteral(x)
- implicit class fromBooleanToLiteral(x: Boolean) extends chisel3.fromBooleanToLiteral(x)
- implicit class fromIntToWidth(x: Int) extends chisel3.fromIntToWidth(x)
-
- @deprecated("Use object firrtl.util.BackendCompilationUtilities instead", "Chisel 3.5")
- type BackendCompilationUtilities = chisel3.BackendCompilationUtilities
- val ImplicitConversions = chisel3.util.ImplicitConversions
-
- // Deprecated as of Chisel3
- object chiselMain {
- import java.io.File
-
- private var target_dir: Option[String] = None
-
- private def parseArgs(args: Array[String]): Unit = {
- for (i <- args.indices) {
- if (args(i) == "--targetDir") {
- target_dir = Some(args(i + 1))
- }
- }
- }
-
- def apply[T <: Module](args: Array[String], gen: () => T): Unit =
- Predef.assert(false, "No more chiselMain in Chisel3")
-
- def run[T <: Module](args: Array[String], gen: () => T): Unit = {
- val circuit = ChiselStage.elaborate(gen())
- parseArgs(args)
- val output_file = new File(target_dir.getOrElse(new File(".").getCanonicalPath) + "/" + circuit.name + ".fir")
-
- (new phases.Emitter)
- .transform(Seq(ChiselCircuitAnnotation(circuit), ChiselOutputFileAnnotation(output_file.toString)))
- }
- }
-
- @deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3")
- object debug {
- def apply(arg: Data): Data = arg
- }
-
- // Deprecated as of Chsiel3
- object throwException {
- @throws(classOf[Exception])
- def apply(s: String, t: Throwable = null): Nothing = {
- val xcpt = new Exception(s, t)
- throw xcpt
- }
- }
-
- object testers {
- type BasicTester = chisel3.testers.BasicTester
- val TesterDriver = chisel3.testers.TesterDriver
- }
-
- val log2Ceil = chisel3.util.log2Ceil
- val log2Floor = chisel3.util.log2Floor
- val isPow2 = chisel3.util.isPow2
-
- /** Compute the log2 rounded up with min value of 1 */
- object log2Up {
- def apply(in: BigInt): Int = {
- require(in >= 0)
- 1.max((in - 1).bitLength)
- }
- def apply(in: Int): Int = apply(BigInt(in))
- }
-
- /** Compute the log2 rounded down with min value of 1 */
- object log2Down {
- def apply(in: BigInt): Int = log2Up(in) - (if (isPow2(in)) 0 else 1)
- def apply(in: Int): Int = apply(BigInt(in))
- }
-
- val BitPat = chisel3.util.BitPat
- type BitPat = chisel3.util.BitPat
-
- implicit class BitsObjectCompatibility(a: BitPat.type) {
- def DC(width: Int): BitPat = a.dontCare(width)
- }
-
- type ArbiterIO[T <: Data] = chisel3.util.ArbiterIO[T]
- type LockingArbiterLike[T <: Data] = chisel3.util.LockingArbiterLike[T]
- type LockingRRArbiter[T <: Data] = chisel3.util.LockingRRArbiter[T]
- type LockingArbiter[T <: Data] = chisel3.util.LockingArbiter[T]
- type RRArbiter[T <: Data] = chisel3.util.RRArbiter[T]
- type Arbiter[T <: Data] = chisel3.util.Arbiter[T]
-
- val FillInterleaved = chisel3.util.FillInterleaved
- val PopCount = chisel3.util.PopCount
- val Fill = chisel3.util.Fill
- val Reverse = chisel3.util.Reverse
-
- val Cat = chisel3.util.Cat
-
- val Log2 = chisel3.util.Log2
-
- type SwitchContext[T <: Bits] = chisel3.util.SwitchContext[T]
- val is = chisel3.util.is
- val switch = chisel3.util.switch
-
- type Counter = chisel3.util.Counter
- val Counter = chisel3.util.Counter
-
- type DecoupledIO[+T <: Data] = chisel3.util.DecoupledIO[T]
- val DecoupledIO = chisel3.util.Decoupled
- val Decoupled = chisel3.util.Decoupled
- type QueueIO[T <: Data] = chisel3.util.QueueIO[T]
-
- val Queue = chisel3.util.Queue
- type Queue[T <: Data] = QueueCompatibility[T]
-
- sealed class QueueCompatibility[T <: Data](
- gen: T,
- entries: Int,
- pipe: Boolean = false,
- flow: Boolean = false
- )(
- implicit compileOptions: chisel3.CompileOptions)
- extends chisel3.util.Queue[T](gen, entries, pipe, flow)(compileOptions) {
-
- def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, override_reset: Option[Bool]) = {
- this(gen, entries, pipe, flow)
- this.override_reset = override_reset
- }
-
- def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool) = {
- this(gen, entries, pipe, flow)
- this.override_reset = Some(_reset)
- }
-
- }
-
- object Enum extends chisel3.util.Enum {
-
- /** Returns n unique values of the specified type. Can be used with unpacking to define enums.
- *
- * nodeType must be of UInt type (note that Bits() creates a UInt) with unspecified width.
- *
- * @example {{{
- * val state_on :: state_off :: Nil = Enum(UInt(), 2)
- * val current_state = UInt()
- * switch (current_state) {
- * is (state_on) {
- * ...
- * }
- * if (state_off) {
- * ...
- * }
- * }
- * }}}
- */
- def apply[T <: Bits](nodeType: T, n: Int): List[T] = {
- require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
- require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
- apply(n).asInstanceOf[List[T]]
- }
-
- /** An old Enum API that returns a map of symbols to UInts.
- *
- * Unlike the new list-based Enum, which can be unpacked into vals that the compiler
- * understands and can check, map accesses can't be compile-time checked and typos may not be
- * caught until runtime.
- *
- * Despite being deprecated, this is not to be removed from the compatibility layer API.
- * Deprecation is only to nag users to do something safer.
- */
- @deprecated("Use list-based Enum", "not soon enough")
- def apply[T <: Bits](nodeType: T, l: Symbol*): Map[Symbol, T] = {
- require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
- require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
- (l.zip(createValues(l.length))).toMap.asInstanceOf[Map[Symbol, T]]
- }
-
- /** An old Enum API that returns a map of symbols to UInts.
- *
- * Unlike the new list-based Enum, which can be unpacked into vals that the compiler
- * understands and can check, map accesses can't be compile-time checked and typos may not be
- * caught until runtime.
- *
- * Despite being deprecated, this is not to be removed from the compatibility layer API.
- * Deprecation is only to nag users to do something safer.
- */
- @deprecated("Use list-based Enum", "not soon enough")
- def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = {
- require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
- require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
- (l.zip(createValues(l.length))).toMap.asInstanceOf[Map[Symbol, T]]
- }
- }
-
- /** LFSR16 generates a 16-bit linear feedback shift register, returning the register contents.
- * This is useful for generating a pseudo-random sequence.
- *
- * The example below, taken from the unit tests, creates two 4-sided dice using `LFSR16` primitives:
- * @example {{{
- * val bins = Reg(Vec(8, UInt(32.W)))
- *
- * // Create two 4 sided dice and roll them each cycle.
- * // Use tap points on each LFSR so values are more independent
- * val die0 = Cat(Seq.tabulate(2) { i => LFSR16()(i) })
- * val die1 = Cat(Seq.tabulate(2) { i => LFSR16()(i + 2) })
- *
- * val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit.
- *
- * bins(rollValue) := bins(rollValue) + 1.U
- *
- * }}}
- */
- object LFSR16 {
-
- /** Generates a 16-bit linear feedback shift register, returning the register contents.
- * @param increment optional control to gate when the LFSR updates.
- */
- def apply(increment: Bool = true.B): UInt =
- VecInit(
- FibonacciLFSR
- .maxPeriod(16, increment, seed = Some(BigInt(1) << 15))
- .asBools
- .reverse
- ).asUInt
-
- }
-
- val ListLookup = chisel3.util.ListLookup
- val Lookup = chisel3.util.Lookup
-
- val Mux1H = chisel3.util.Mux1H
- val PriorityMux = chisel3.util.PriorityMux
- val MuxLookup = chisel3.util.MuxLookup
- val MuxCase = chisel3.util.MuxCase
-
- val OHToUInt = chisel3.util.OHToUInt
- val PriorityEncoder = chisel3.util.PriorityEncoder
- val UIntToOH = chisel3.util.UIntToOH
- val PriorityEncoderOH = chisel3.util.PriorityEncoderOH
-
- val RegEnable = chisel3.util.RegEnable
- val ShiftRegister = chisel3.util.ShiftRegister
-
- type ValidIO[+T <: Data] = chisel3.util.Valid[T]
- val Valid = chisel3.util.Valid
- val Pipe = chisel3.util.Pipe
- type Pipe[T <: Data] = chisel3.util.Pipe[T]
-
- /** Package for experimental features, which may have their API changed, be removed, etc.
- *
- * Because its contents won't necessarily have the same level of stability and support as
- * non-experimental, you must explicitly import this package to use its contents.
- */
- object experimental {
- import scala.annotation.compileTimeOnly
-
- class dump extends chisel3.internal.naming.dump
- class treedump extends chisel3.internal.naming.treedump
- class chiselName extends chisel3.internal.naming.chiselName
- }
-
- implicit class DataCompatibility(a: Data) {
- import chisel3.internal.sourceinfo.DeprecatedSourceInfo
-
- def toBits(implicit compileOptions: CompileOptions): UInt = a.do_asUInt(DeprecatedSourceInfo, compileOptions)
-
- }
-
- implicit class VecLikeCompatibility[T <: Data](a: VecLike[T]) {
- import chisel3.internal.sourceinfo.DeprecatedSourceInfo
-
- def read(idx: UInt)(implicit compileOptions: CompileOptions): T = a.do_apply(idx)(compileOptions)
-
- def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit =
- a.do_apply(idx)(compileOptions).:=(data)(DeprecatedSourceInfo, compileOptions)
-
- }
-
- implicit class BitsCompatibility(a: Bits) {
- import chisel3.internal.sourceinfo.DeprecatedSourceInfo
-
- final def asBits(implicit compileOptions: CompileOptions): Bits = a.do_asUInt(DeprecatedSourceInfo, compileOptions)
-
- final def toSInt(implicit compileOptions: CompileOptions): SInt = a.do_asSInt(DeprecatedSourceInfo, compileOptions)
-
- final def toUInt(implicit compileOptions: CompileOptions): UInt = a.do_asUInt(DeprecatedSourceInfo, compileOptions)
-
- final def toBools(implicit compileOptions: CompileOptions): Seq[Bool] =
- a.do_asBools(DeprecatedSourceInfo, compileOptions)
- }
-
-}
diff --git a/src/main/scala/chisel3/experimental/conversions/package.scala b/src/main/scala/chisel3/experimental/conversions/package.scala
deleted file mode 100644
index 7374f223..00000000
--- a/src/main/scala/chisel3/experimental/conversions/package.scala
+++ /dev/null
@@ -1,240 +0,0 @@
-package chisel3.experimental
-
-import chisel3._
-import chisel3.experimental.dataview._
-import scala.language.implicitConversions
-
-/** Implicit conversions from some Scala standard library types and [[Data]]
- *
- * @note As this leans heavily on the experimental [[DataView]] feature, these APIs are experimental and subject to change
- */
-package object conversions {
-
- /** Implicit conversion between `Seq` and `Vec` */
- implicit def seq2vec[A: DataProduct, B <: Data](xs: Seq[A])(implicit dv: DataView[A, B]): Vec[B] =
- xs.viewAs[Vec[B]]
-
- /** Implicit conversion between [[Tuple2]] and [[HWTuple2]] */
- implicit def tuple2hwtuple[T1: DataProduct, T2: DataProduct, V1 <: Data, V2 <: Data](
- tup: (T1, T2)
- )(
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2]
- ): HWTuple2[V1, V2] = {
- tup.viewAs[HWTuple2[V1, V2]]
- }
-
- /** Implicit conversion between [[Tuple3]] and [[HWTuple3]] */
- implicit def tuple3hwtuple[T1: DataProduct, T2: DataProduct, T3: DataProduct, V1 <: Data, V2 <: Data, V3 <: Data](
- tup: (T1, T2, T3)
- )(
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3]
- ): HWTuple3[V1, V2, V3] = {
- tup.viewAs[HWTuple3[V1, V2, V3]]
- }
-
- /** Implicit conversion between [[Tuple4]] and [[HWTuple4]] */
- implicit def tuple4hwtuple[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data
- ](tup: (T1, T2, T3, T4)
- )(
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4]
- ): HWTuple4[V1, V2, V3, V4] = {
- tup.viewAs[HWTuple4[V1, V2, V3, V4]]
- }
-
- /** Implicit conversion between [[Tuple5]] and [[HWTuple5]] */
- implicit def tuple5hwtuple[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data
- ](tup: (T1, T2, T3, T4, T5)
- )(
- implicit v1: DataView[T1, V1],
- v2: DataView[T2, V2],
- v3: DataView[T3, V3],
- v4: DataView[T4, V4],
- v5: DataView[T5, V5]
- ): HWTuple5[V1, V2, V3, V4, V5] = {
- tup.viewAs[HWTuple5[V1, V2, V3, V4, V5]]
- }
-
- /** Implicit conversion between [[Tuple6]] and [[HWTuple6]] */
- implicit def tuple6hwtuple[
- T1: DataProduct,
- T2: DataProduct,
- T3: DataProduct,
- T4: DataProduct,
- T5: DataProduct,
- T6: DataProduct,
- V1 <: Data,
- V2 <: Data,
- V3 <: Data,
- V4 <: Data,
- V5 <: Data,
- V6 <: Data
- ](tup: (T1, T2, T3, T4, T5, T6)
- )(
- 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]
- ): HWTuple6[V1, V2, V3, V4, V5, V6] = {
- tup.viewAs[HWTuple6[V1, V2, V3, V4, V5, V6]]
- }
-
- /** Implicit conversion between [[Tuple7]] and [[HWTuple7]] */
- implicit def tuple7hwtuple[
- 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
- ](tup: (T1, T2, T3, T4, T5, T6, T7)
- )(
- 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]
- ): HWTuple7[V1, V2, V3, V4, V5, V6, V7] = {
- tup.viewAs[HWTuple7[V1, V2, V3, V4, V5, V6, V7]]
- }
-
- /** Implicit conversion between [[Tuple8]] and [[HWTuple8]] */
- implicit def tuple8hwtuple[
- 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
- ](tup: (T1, T2, T3, T4, T5, T6, T7, T8)
- )(
- 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]
- ): HWTuple8[V1, V2, V3, V4, V5, V6, V7, V8] = {
- tup.viewAs[HWTuple8[V1, V2, V3, V4, V5, V6, V7, V8]]
- }
-
- /** Implicit conversion between [[Tuple9]] and [[HWTuple9]] */
- implicit def tuple9hwtuple[
- 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
- ](tup: (T1, T2, T3, T4, T5, T6, T7, T8, T9)
- )(
- 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]
- ): HWTuple9[V1, V2, V3, V4, V5, V6, V7, V8, V9] = {
- tup.viewAs[HWTuple9[V1, V2, V3, V4, V5, V6, V7, V8, V9]]
- }
-
- /** Implicit conversion between [[Tuple10]] and [[HWTuple10]] */
- implicit def tuple10hwtuple[
- 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
- ](tup: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
- )(
- 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]
- ): HWTuple10[V1, V2, V3, V4, V5, V6, V7, V8, V9, V10] = {
- tup.viewAs[HWTuple10[V1, V2, V3, V4, V5, V6, V7, V8, V9, V10]]
- }
-}
diff --git a/src/main/scala/chisel3/stage/ChiselPhase.scala b/src/main/scala/chisel3/stage/ChiselPhase.scala
index 6c7affbc..050ba8fa 100644
--- a/src/main/scala/chisel3/stage/ChiselPhase.scala
+++ b/src/main/scala/chisel3/stage/ChiselPhase.scala
@@ -18,7 +18,6 @@ private[chisel3] object ChiselPhase {
Dependency[chisel3.stage.phases.Checks],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.AddSerializationAnnotations],
Dependency[chisel3.stage.phases.Convert],
Dependency[chisel3.stage.phases.MaybeFirrtlStage]
diff --git a/src/main/scala/chisel3/stage/ChiselStage.scala b/src/main/scala/chisel3/stage/ChiselStage.scala
index 1224a8f1..2d4f26b0 100644
--- a/src/main/scala/chisel3/stage/ChiselStage.scala
+++ b/src/main/scala/chisel3/stage/ChiselStage.scala
@@ -158,7 +158,6 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert]
)
}
@@ -179,7 +178,6 @@ object ChiselStage {
override val targets = Seq(
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert]
)
}
@@ -207,7 +205,6 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
@@ -233,7 +230,6 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
@@ -258,7 +254,6 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
diff --git a/src/main/scala/chisel3/stage/phases/AspectPhase.scala b/src/main/scala/chisel3/stage/phases/AspectPhase.scala
deleted file mode 100644
index efe2c3a4..00000000
--- a/src/main/scala/chisel3/stage/phases/AspectPhase.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.stage.phases
-
-import chisel3.aop.Aspect
-import chisel3.RawModule
-import chisel3.stage.DesignAnnotation
-import firrtl.AnnotationSeq
-import firrtl.options.Phase
-
-import scala.collection.mutable
-
-/** Phase that consumes all Aspects and calls their toAnnotationSeq methods.
- *
- * Consumes the [[chisel3.stage.DesignAnnotation]] and converts every [[Aspect]] into their annotations prior to executing FIRRTL
- */
-class AspectPhase extends Phase {
- def transform(annotations: AnnotationSeq): AnnotationSeq = {
- var dut: Option[RawModule] = None
- val aspects = mutable.ArrayBuffer[Aspect[_]]()
-
- val remainingAnnotations = annotations.flatMap {
- case DesignAnnotation(d) =>
- dut = Some(d)
- Nil
- case a: Aspect[_] =>
- aspects += a
- Nil
- case other => Seq(other)
- }
- if (dut.isDefined) {
- val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get, remainingAnnotations) }
- remainingAnnotations ++ newAnnotations
- } else annotations
- }
-}
diff --git a/src/main/scala/chisel3/stage/phases/Emitter.scala b/src/main/scala/chisel3/stage/phases/Emitter.scala
index 254f8add..67bb1486 100644
--- a/src/main/scala/chisel3/stage/phases/Emitter.scala
+++ b/src/main/scala/chisel3/stage/phases/Emitter.scala
@@ -29,7 +29,6 @@ class Emitter extends Phase {
Dependency[Elaborate],
Dependency[AddImplicitOutputFile],
Dependency[AddImplicitOutputAnnotationFile],
- Dependency[MaybeAspectPhase]
)
override def optionalPrerequisites = Seq.empty
override def optionalPrerequisiteOf = Seq(Dependency[Convert])
diff --git a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala
deleted file mode 100644
index dcd0dfe0..00000000
--- a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.stage.phases
-
-import chisel3.aop.Aspect
-import firrtl.AnnotationSeq
-import firrtl.options.{Dependency, Phase}
-
-/** Run [[AspectPhase]] if a [[chisel3.aop.Aspect]] is present.
- */
-class MaybeAspectPhase extends Phase {
-
- override def prerequisites = Seq(Dependency[Elaborate])
- override def optionalPrerequisites = Seq.empty
- override def optionalPrerequisiteOf = Seq.empty
- override def invalidates(a: Phase) = false
-
- def transform(annotations: AnnotationSeq): AnnotationSeq = {
- if (annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) {
- new AspectPhase().transform(annotations)
- } else annotations
- }
-}
diff --git a/src/main/scala/chisel3/util/BlackBoxUtils.scala b/src/main/scala/chisel3/util/BlackBoxUtils.scala
deleted file mode 100644
index 579a6307..00000000
--- a/src/main/scala/chisel3/util/BlackBoxUtils.scala
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.util
-
-import chisel3._
-import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform}
-import firrtl.transforms.{BlackBoxInlineAnno, BlackBoxNotFoundException, BlackBoxPathAnno, BlackBoxSourceHelper}
-import firrtl.annotations.ModuleName
-import logger.LazyLogging
-
-private[util] object BlackBoxHelpers {
-
- implicit class BlackBoxInlineAnnoHelpers(anno: BlackBoxInlineAnno.type) extends LazyLogging {
-
- /** Generate a BlackBoxInlineAnno from a Java Resource and a module name. */
- def fromResource(resourceName: String, moduleName: ModuleName) = try {
- val blackBoxFile = os.resource / os.RelPath(resourceName.dropWhile(_ == '/'))
- val contents = os.read(blackBoxFile)
- if (contents.size > BigInt(2).pow(20)) {
- val message =
- s"Black box resource $resourceName, which will be converted to an inline annotation, is greater than 1 MiB." +
- "This may affect compiler performance. Consider including this resource via a black box path."
- logger.warn(message)
- }
- BlackBoxInlineAnno(moduleName, blackBoxFile.last, contents)
- } catch {
- case e: os.ResourceNotFoundException =>
- throw new BlackBoxNotFoundException(resourceName, e.getMessage)
- }
- }
-}
-
-import BlackBoxHelpers._
-
-trait HasBlackBoxResource extends BlackBox {
- self: BlackBox =>
-
- /** Copies a Java resource containing some text into the output directory. This is typically used to copy a Verilog file
- * to the final output directory, but may be used to copy any Java resource (e.g., a C++ testbench).
- *
- * Resource files are located in project_root/src/main/resources/.
- * Example of adding the resource file project_root/src/main/resources/blackbox.v:
- * {{{
- * addResource("/blackbox.v")
- * }}}
- */
- def addResource(blackBoxResource: String): Unit = {
- val anno = new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl = BlackBoxInlineAnno.fromResource(blackBoxResource, self.toNamed)
- def transformClass = classOf[BlackBoxSourceHelper]
- }
- chisel3.experimental.annotate(anno)
- }
-}
-
-trait HasBlackBoxInline extends BlackBox {
- self: BlackBox =>
-
- /** Creates a black box verilog file, from the contents of a local string
- *
- * @param blackBoxName The black box module name, to create filename
- * @param blackBoxInline The black box contents
- */
- def setInline(blackBoxName: String, blackBoxInline: String): Unit = {
- val anno = new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl = BlackBoxInlineAnno(self.toNamed, blackBoxName, blackBoxInline)
- def transformClass = classOf[BlackBoxSourceHelper]
- }
- chisel3.experimental.annotate(anno)
- }
-}
-
-trait HasBlackBoxPath extends BlackBox {
- self: BlackBox =>
-
- /** Copies a file to the target directory
- *
- * This works with absolute and relative paths. Relative paths are relative
- * to the current working directory, which is generally not the same as the
- * target directory.
- */
- def addPath(blackBoxPath: String): Unit = {
- val anno = new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl = BlackBoxPathAnno(self.toNamed, blackBoxPath)
- def transformClass = classOf[BlackBoxSourceHelper]
- }
- chisel3.experimental.annotate(anno)
- }
-}
diff --git a/src/main/scala/chisel3/util/ExtModuleUtils.scala b/src/main/scala/chisel3/util/ExtModuleUtils.scala
deleted file mode 100644
index 8a687d36..00000000
--- a/src/main/scala/chisel3/util/ExtModuleUtils.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.util
-
-import chisel3.experimental.{ChiselAnnotation, ExtModule, RunFirrtlTransform}
-import firrtl.transforms.{BlackBoxInlineAnno, BlackBoxNotFoundException, BlackBoxPathAnno, BlackBoxSourceHelper}
-
-import BlackBoxHelpers._
-
-trait HasExtModuleResource extends ExtModule {
- self: ExtModule =>
-
- /** Copies a resource file to the target directory
- *
- * Resource files are located in project_root/src/main/resources/.
- * Example of adding the resource file project_root/src/main/resources/blackbox.v:
- * {{{
- * addResource("/blackbox.v")
- * }}}
- */
- def addResource(blackBoxResource: String): Unit = {
- val anno = new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl = BlackBoxInlineAnno.fromResource(blackBoxResource, self.toNamed)
- def transformClass = classOf[BlackBoxSourceHelper]
- }
- chisel3.experimental.annotate(anno)
- }
-}
-
-trait HasExtModuleInline extends ExtModule {
- self: ExtModule =>
-
- /** Creates a black box verilog file, from the contents of a local string
- *
- * @param blackBoxName The black box module name, to create filename
- * @param blackBoxInline The black box contents
- */
- def setInline(blackBoxName: String, blackBoxInline: String): Unit = {
- val anno = new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl = BlackBoxInlineAnno(self.toNamed, blackBoxName, blackBoxInline)
- def transformClass = classOf[BlackBoxSourceHelper]
- }
- chisel3.experimental.annotate(anno)
- }
-}
-
-trait HasExtModulePath extends ExtModule {
- self: ExtModule =>
-
- /** Copies a file to the target directory
- *
- * This works with absolute and relative paths. Relative paths are relative
- * to the current working directory, which is generally not the same as the
- * target directory.
- */
- def addPath(blackBoxPath: String): Unit = {
- val anno = new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl = BlackBoxPathAnno(self.toNamed, blackBoxPath)
- def transformClass = classOf[BlackBoxSourceHelper]
- }
- chisel3.experimental.annotate(anno)
- }
-}
diff --git a/src/main/scala/chisel3/util/Math.scala b/src/main/scala/chisel3/util/Math.scala
index 6eab9241..1fc45650 100644
--- a/src/main/scala/chisel3/util/Math.scala
+++ b/src/main/scala/chisel3/util/Math.scala
@@ -23,11 +23,10 @@ import chisel3.internal
* }}}
*/
object log2Up {
- // Do not deprecate until zero-width wires fully work:
- // https://github.com/freechipsproject/chisel3/issues/847
- //@chiselRuntimeDeprecated
- //@deprecated("Use log2Ceil instead", "chisel3")
- def apply(in: BigInt): Int = Chisel.log2Up(in)
+ def apply(in: BigInt): Int = {
+ require(in >= 0)
+ 1.max((in - 1).bitLength)
+ }
}
/** Compute the log2 of a Scala integer, rounded up.
@@ -66,7 +65,7 @@ object log2Down {
// https://github.com/freechipsproject/chisel3/issues/847
//@chiselRuntimeDeprecated
//@deprecated("Use log2Floor instead", "chisel3")
- def apply(in: BigInt): Int = Chisel.log2Down(in)
+ def apply(in: BigInt): Int = log2Up(in) - (if (isPow2(in)) 0 else 1)
}
/** Compute the log2 of a Scala integer, rounded down.