Skip to content

Commit a0ac3fd

Browse files
authored
Add DataProduct for Iterables and primitive types (#3856)
1 parent eadde6f commit a0ac3fd

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala

+33-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ trait DataProduct[-A] {
4646

4747
/** Low priority built-in implementations of [[DataProduct]]
4848
*
49-
* @note This trait exists so that `dataDataProduct` can be lower priority than `seqDataProduct` to resolve ambiguity
49+
* @note This trait exists so that `dataDataProduct` can be lower priority than `iterableDataProduct` to resolve ambiguity
5050
*/
5151
sealed trait LowPriorityDataProduct {
5252

@@ -63,6 +63,25 @@ sealed trait LowPriorityDataProduct {
6363
*/
6464
object DataProduct extends LowPriorityDataProduct {
6565

66+
/** Factory method for constructing [[DataProduct]]s */
67+
def apply[A](f: (A, String) => Iterator[(Data, String)]): DataProduct[A] = new DataProduct[A] {
68+
def dataIterator(a: A, path: String): Iterator[(Data, String)] = f(a, path)
69+
}
70+
71+
/** Factory for constructing [[DataProduct]] for types that do not contain any [[Data]] */
72+
def empty[A]: DataProduct[A] = apply[A] { case _ => Iterator.empty }
73+
74+
// DataProducts for simple primitive types
75+
implicit val charDataProduct: DataProduct[Char] = empty
76+
implicit val stringDataProduct: DataProduct[String] = empty
77+
implicit val intDataProduct: DataProduct[Int] = empty
78+
implicit val byteDataProduct: DataProduct[Byte] = empty
79+
implicit val shortDataProduct: DataProduct[Short] = empty
80+
implicit val longDataProduct: DataProduct[Long] = empty
81+
implicit val bigIntDataProduct: DataProduct[BigInt] = empty
82+
implicit val floatDataProduct: DataProduct[Float] = empty
83+
implicit val doubleDataProduct: DataProduct[Double] = empty
84+
6685
/** [[DataProduct]] implementation for [[BaseModule]] */
6786
implicit val userModuleDataProduct: DataProduct[BaseModule] = new DataProduct[BaseModule] {
6887
def dataIterator(a: BaseModule, path: String): Iterator[(Data, String)] = {
@@ -82,7 +101,8 @@ object DataProduct extends LowPriorityDataProduct {
82101
}
83102

84103
/** [[DataProduct]] implementation for any `Seq[A]` where `A` has an implementation of `DataProduct`. */
85-
implicit def seqDataProduct[A: DataProduct]: DataProduct[Seq[A]] = new DataProduct[Seq[A]] {
104+
@deprecated("Use iterableDataProduct instead", "Chisel 7.0")
105+
def seqDataProduct[A: DataProduct]: DataProduct[Seq[A]] = new DataProduct[Seq[A]] {
86106
def dataIterator(a: Seq[A], path: String): Iterator[(Data, String)] = {
87107
val dpa = implicitly[DataProduct[A]]
88108
a.iterator.zipWithIndex.flatMap {
@@ -92,6 +112,17 @@ object DataProduct extends LowPriorityDataProduct {
92112
}
93113
}
94114

115+
/** [[DataProduct]] implementation for any `Iterable[A]` where `A` has an implementation of `DataProduct`. */
116+
implicit def iterableDataProduct[A: DataProduct, F[A] <: IterableOnce[A]]: DataProduct[F[A]] = new DataProduct[F[A]] {
117+
def dataIterator(a: F[A], path: String): Iterator[(Data, String)] = {
118+
val dpa = implicitly[DataProduct[A]]
119+
a.iterator.zipWithIndex.flatMap {
120+
case (elt, idx) =>
121+
dpa.dataIterator(elt, s"$path[$idx]")
122+
}
123+
}
124+
}
125+
95126
/** [[DataProduct]] implementation for any [[scala.Tuple2]] where each field has an implementation of `DataProduct`. */
96127
implicit def tuple2DataProduct[A: DataProduct, B: DataProduct]: DataProduct[(A, B)] = new DataProduct[(A, B)] {
97128
def dataIterator(tup: (A, B), path: String): Iterator[(Data, String)] = {

core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ object Lookupable {
514514
implicit val lookupShort: SimpleLookupable[Short] = new SimpleLookupable[Short]()
515515
implicit val lookupLong: SimpleLookupable[Long] = new SimpleLookupable[Long]()
516516
implicit val lookupFloat: SimpleLookupable[Float] = new SimpleLookupable[Float]()
517+
implicit val lookupDouble: SimpleLookupable[Double] = new SimpleLookupable[Double]()
517518
implicit val lookupChar: SimpleLookupable[Char] = new SimpleLookupable[Char]()
518519
implicit val lookupString: SimpleLookupable[String] = new SimpleLookupable[String]()
519520
implicit val lookupBoolean: SimpleLookupable[Boolean] = new SimpleLookupable[Boolean]()

src/test/scala/chiselTests/experimental/DataView.scala

+39
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,45 @@ class DataViewSpec extends ChiselFlatSpec {
552552
verilog should include("assign z = sel ? b : d;")
553553
}
554554

555+
it should "support primitive types in the view target" in {
556+
class MyBundle(val name: String) extends Bundle {
557+
val x = UInt(8.W)
558+
}
559+
implicit val view: DataView[(UInt, Char, String, Int, Byte, Short, Long, BigInt, Float, Double), MyBundle] =
560+
DataView(
561+
tup => new MyBundle(tup.productIterator.toList.tail.mkString("_")),
562+
_._1 -> _.x
563+
)
564+
class MyModule extends Module {
565+
val in = IO(Input(UInt(8.W)))
566+
val bun = (in, 'a', "b", 0, 1.toByte, 2.toShort, 3L, BigInt(4), 5.0f, 6.0).viewAs[MyBundle]
567+
val out = IO(Output(chiselTypeOf(bun)))
568+
out := bun
569+
bun.name should be("a_b_0_1_2_3_4_5.0_6.0")
570+
}
571+
val chirrtl = ChiselStage.emitCHIRRTL(new MyModule)
572+
chirrtl should include("connect out.x, in")
573+
}
574+
575+
it should "support views of Options" in {
576+
class MyBundle(w: Option[Int]) extends Bundle {
577+
val x = w.map(v => UInt(v.W))
578+
}
579+
implicit val view: DataView[Option[UInt], MyBundle] = DataView.mapping(
580+
opt => new MyBundle(opt.map(_.getWidth)),
581+
{ case (opt, bun) => opt.zip(bun.x).map { case (o, b) => o -> b } }
582+
)
583+
class MyModule extends Module {
584+
val in = IO(Input(UInt(8.W)))
585+
val out1 = IO(Output(new MyBundle(Some(8))))
586+
val out2 = IO(Output(new MyBundle(None)))
587+
out1 := Option(in).viewAs[MyBundle]
588+
out2 := Option.empty[UInt].viewAs[MyBundle]
589+
}
590+
val chirrtl = ChiselStage.emitCHIRRTL(new MyModule)
591+
chirrtl should include("connect out1.x, in")
592+
}
593+
555594
// This example should be turned into a built-in feature
556595
it should "enable viewing Seqs as Vecs" in {
557596

0 commit comments

Comments
 (0)