summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/experimental
diff options
context:
space:
mode:
authorAditya Naik2024-05-03 10:59:45 -0700
committerAditya Naik2024-05-03 10:59:45 -0700
commit878d488a7c8e0d6973de58b3164022c6a102e449 (patch)
treecd081bbcbe3f797f80b10c2d8153da0069750e51 /core/src/main/scala/chisel3/experimental
parent8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff)
Get cleanup to compile
Diffstat (limited to 'core/src/main/scala/chisel3/experimental')
-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
15 files changed, 2 insertions, 2329 deletions
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