Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implement DataViews for Seq and Tuple #2277

Merged
merged 5 commits into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 244 additions & 4 deletions core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package chisel3.experimental.dataview

import chisel3.experimental.BaseModule
import chisel3.{Data, getRecursiveFields}
import chisel3.{Data, Vec, getRecursiveFields}

import scala.annotation.implicitNotFound

Expand Down Expand Up @@ -41,17 +41,24 @@ trait DataProduct[-A] {
def dataSet(a: A): Data => Boolean = dataIterator(a, "").map(_._1).toSet
}

/** Encapsulating object for automatically provided implementations of [[DataProduct]]
/** Low priority built-in implementations of [[DataProduct]]
*
* @note DataProduct implementations provided in this object are available in the implicit scope
* @note This trait exists so that `dataDataProduct` can be lower priority than `seqDataProduct` to resolve ambiguity
*/
object DataProduct {
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)] = {
Expand All @@ -69,4 +76,237 @@ object DataProduct {
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")
}
}
}
Loading