summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Koenig2021-12-10 15:56:56 -0800
committerGitHub2021-12-10 15:56:56 -0800
commit630d05bdca90ec1c80eaaa7834e755f51095463d (patch)
treeb310b410326082947fa3db39f7645c02e80e6913
parent3f21bbb52363c3105f6a0ff961fa7a411dd0c7ab (diff)
Add support for dynamic indexing on Vec identity views (#2298)
-rw-r--r--core/src/main/scala/chisel3/Aggregate.scala15
-rw-r--r--src/test/scala/chiselTests/experimental/DataView.scala21
2 files changed, 33 insertions, 3 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala
index 6c6d89c3..dbde7068 100644
--- a/core/src/main/scala/chisel3/Aggregate.scala
+++ b/core/src/main/scala/chisel3/Aggregate.scala
@@ -3,7 +3,7 @@
package chisel3
import chisel3.experimental.VecLiterals.AddVecLiteralConstructor
-import chisel3.experimental.dataview.{InvalidViewException, isView}
+import chisel3.experimental.dataview.{InvalidViewException, isView, reifySingleData}
import scala.collection.immutable.{SeqMap, VectorMap}
import scala.collection.mutable.{HashSet, LinkedHashMap}
@@ -258,9 +258,20 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int)
def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T = {
requireIsHardware(this, "vec")
requireIsHardware(p, "vec index")
+
+ // Special handling for views
if (isView(this)) {
- throw InvalidViewException("Dynamic indexing of Views is not yet supported")
+ reifySingleData(this) match {
+ // Views complicate things a bit, but views that correspond exactly to an identical Vec can just forward the
+ // dynamic indexing to the target Vec
+ // In theory, we could still do this forwarding if the sample element were different by deriving a DataView
+ case Some(target: Vec[T @unchecked]) if this.length == target.length &&
+ this.sample_element.typeEquivalent(target.sample_element) =>
+ return target.do_apply(p)
+ case _ => throw InvalidViewException("Dynamic indexing of Views is not yet supported")
+ }
}
+
val port = gen
// Reconstruct the resolvedDirection (in Aggregate.bind), since it's not stored.
diff --git a/src/test/scala/chiselTests/experimental/DataView.scala b/src/test/scala/chiselTests/experimental/DataView.scala
index 399b0cbc..7c5d170b 100644
--- a/src/test/scala/chiselTests/experimental/DataView.scala
+++ b/src/test/scala/chiselTests/experimental/DataView.scala
@@ -313,8 +313,26 @@ class DataViewSpec extends ChiselFlatSpec {
verilog should include ("assign z = d;")
}
- it should "error if you try to dynamically index a Vec view" in {
+ it should "support dynamic indexing for Vec identity views" in {
+ class MyModule extends Module {
+ val dataIn = IO(Input(UInt(8.W)))
+ val addr = IO(Input(UInt(2.W)))
+ val dataOut = IO(Output(UInt(8.W)))
+
+ val vec = RegInit(0.U.asTypeOf(Vec(4, UInt(8.W))))
+ val view = vec.viewAs[Vec[UInt]]
+ // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
+ // This style is not recommended, this is just testing the behavior
+ val selected = view(addr)
+ selected := dataIn
+ dataOut := selected
+ }
+ val chirrtl = ChiselStage.emitChirrtl(new MyModule)
+ chirrtl should include ("vec[addr] <= dataIn")
+ chirrtl should include ("dataOut <= vec[addr]")
+ }
+ it should "error if you try to dynamically index a Vec view that does not correspond to a Vec target" in {
class MyModule extends Module {
val inA, inB = IO(Input(UInt(8.W)))
val outA, outB = IO(Output(UInt(8.W)))
@@ -323,6 +341,7 @@ class DataViewSpec extends ChiselFlatSpec {
val a, b, c, d = RegInit(0.U)
// Dynamic indexing is more of a "generator" in Chisel3 than an individual node
+ // This style is not recommended, this is just testing the behavior
val selected = Seq((a, b), (c, d)).apply(idx)
selected := (inA, inB)
(outA, outB) := selected