diff options
| author | Jack Koenig | 2022-01-10 10:39:52 -0800 |
|---|---|---|
| committer | Jack Koenig | 2022-01-10 15:53:55 -0800 |
| commit | 3131c0daad41dea78bede4517669e376c41a325a (patch) | |
| tree | 55baed78a6a01f80ff3952a08233ca553a19964f /core/src/main/scala/chisel3/experimental/dataview | |
| parent | dd36f97a82746cec0b25b94651581fe799e24579 (diff) | |
Apply scalafmt
Command:
sbt scalafmtAll
Diffstat (limited to 'core/src/main/scala/chisel3/experimental/dataview')
3 files changed, 508 insertions, 274 deletions
diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala b/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala index 438f97b8..c6ebe604 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala @@ -3,7 +3,7 @@ package chisel3.experimental.dataview import chisel3.experimental.BaseModule -import chisel3.{Data, Vec, getRecursiveFields} +import chisel3.{getRecursiveFields, Data, Vec} import scala.annotation.implicitNotFound @@ -18,9 +18,12 @@ import scala.annotation.implicitNotFound * @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") +@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 @@ -59,6 +62,7 @@ sealed trait LowPriorityDataProduct { * @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)] = { @@ -78,19 +82,18 @@ object DataProduct extends LowPriorityDataProduct { } /** [[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]] { + 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) => + 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)] { + 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]] @@ -100,7 +103,7 @@ object DataProduct extends LowPriorityDataProduct { } /** [[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)] = + 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]] @@ -112,7 +115,12 @@ object DataProduct extends LowPriorityDataProduct { } /** [[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)] = + 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]] @@ -129,11 +137,12 @@ object DataProduct extends LowPriorityDataProduct { /** [[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)] = + 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]] @@ -152,12 +161,13 @@ object DataProduct extends LowPriorityDataProduct { /** [[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)] = + 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]] @@ -178,13 +188,14 @@ object DataProduct extends LowPriorityDataProduct { /** [[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)] = + 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]] @@ -207,14 +218,15 @@ object DataProduct extends LowPriorityDataProduct { /** [[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)] = + 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]] @@ -239,15 +251,16 @@ object DataProduct extends LowPriorityDataProduct { /** [[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)] = + 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]] @@ -274,16 +287,17 @@ object DataProduct extends LowPriorityDataProduct { /** [[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)] = + 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]] diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala index c17a5574..7f20964d 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala @@ -11,7 +11,6 @@ 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. @@ -41,9 +40,11 @@ import annotation.implicitNotFound * @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] ( +@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 */ @@ -51,8 +52,8 @@ sealed class DataView[T : DataProduct, V <: Data] private[chisel3] ( // Aliasing this with a def below to make the ScalaDoc show up for the field _total: Boolean )( - implicit private[chisel3] val sourceInfo: SourceInfo -) { + implicit private[chisel3] val sourceInfo: SourceInfo) { + /** Indicates if the mapping contains every field of the target */ def total: Boolean = _total @@ -89,15 +90,30 @@ sealed class DataView[T : DataProduct, V <: Data] private[chisel3] ( 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] = + 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] = + 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] = + 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 @@ -107,7 +123,7 @@ object DataView { * * @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]) { + 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 @@ -143,7 +159,10 @@ object DataView { 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]] = { + 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 @@ -151,223 +170,395 @@ object DataView { ) } - /** 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 + /** 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) + { 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 + /** 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) + { 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]] */ + /** 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 + 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 + 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) + { + 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]] */ + /** 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 + 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 + 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 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) + { + 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]] */ + /** 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, + 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 + 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) => + 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) + { + 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]] */ + /** 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 + 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 + 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) => + 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) + { + 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]] */ + /** 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 + 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 + 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) => + 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) + { + 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]] */ + /** 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 + 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 + 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) => + 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) + { + 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]] */ + /** 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 + 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 + 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) => + 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) + { + 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 + ) } ) } @@ -376,14 +567,29 @@ object DataView { 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] = + 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] = + 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] = + 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) } diff --git a/core/src/main/scala/chisel3/experimental/dataview/package.scala b/core/src/main/scala/chisel3/experimental/dataview/package.scala index 1acf43e1..3278d82c 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/package.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/package.scala @@ -39,27 +39,39 @@ package object dataview { } // 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") + @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 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.mapping[T, V](_ => proto, { - 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 - }) + implicit val dataView = PartialDataView.mapping[T, V]( + _ => proto, + { + 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 + } + ) target.viewAs[V] } } - private def nonTotalViewException(dataView: DataView[_, _], target: Any, view: Data, targetFields: Seq[String], viewFields: Seq[String]) = { + 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 { @@ -77,18 +89,17 @@ package object dataview { } // 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 = { + 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) + val targetContains: Data => Boolean = implicitly[DataProduct[T]].dataSet(target) // Resulting bindings for each Element of the View val childBindings = new mutable.HashMap[Data, mutable.ListBuffer[Element]] ++ - viewFieldLookup.view - .collect { case (elt: Element, _) => elt } + viewFieldLookup.view.collect { case (elt: Element, _) => elt } .map(_ -> new mutable.ListBuffer[Element]) def viewFieldName(d: Data): String = @@ -115,7 +126,9 @@ package object dataview { 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}") + throw InvalidViewException( + s"View field $fieldName has width ${vwidth} that is incompatible with target value $tex's width ${twidth}" + ) } childBindings(vex) += tex } @@ -137,23 +150,24 @@ package object dataview { } // Errors in totality of the View, use var List to keep fast path cheap (no allocation) - var viewNonTotalErrors: List[Data] = Nil + 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 resultBindings = childBindings.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 + val resultBindings = childBindings.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 @@ -169,7 +183,7 @@ package object dataview { } view match { - case elt: Element => view.bind(ViewBinding(resultBindings(elt))) + case elt: Element => view.bind(ViewBinding(resultBindings(elt))) case agg: Aggregate => // We record total Data mappings to provide a better .toTarget val topt = target match { @@ -221,31 +235,31 @@ package object dataview { @tailrec private[chisel3] def reify(elt: Element, topBinding: TopBinding): Element = topBinding match { case ViewBinding(target) => reify(target, elt.topBinding) - case _ => elt + 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.binding.collect { // First check if this is a total mapping of an Aggregate - case AggregateViewBinding(_, Some(t)) => t - }.orElse { // Otherwise look via top binding - data.topBindingOpt match { - case None => None - case Some(ViewBinding(target)) => Some(target) - case Some(AggregateViewBinding(lookup, _)) => lookup.get(data) - case Some(_) => None - } + /** 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.binding.collect { // First check if this is a total mapping of an Aggregate + case AggregateViewBinding(_, Some(t)) => t + }.orElse { // Otherwise look via top binding + 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) } + candidate.flatMap { d => + // Candidate may itself be a view, keep tracing in those cases + if (isView(d)) reifySingleData(d) else Some(d) } + } } |
