summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Koenig2019-10-08 07:23:52 -0700
committerSchuyler Eldridge2019-10-08 10:23:52 -0400
commitfafd984a923591841917cd4c3a1f4c823dc485b4 (patch)
tree3b2fc032baa424351cc151e4ae2bb85eab51579b
parent98bfe2416676651b29cd40fc8388c16bfda467d6 (diff)
Fix direction of dynamic index in complex Vec (#1196)
Dynamically indexing a Vec of Flipped bidirectional Bundles would get the wrong directions on the elements of the Bundles Fixes #1192
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Aggregate.scala4
-rw-r--r--src/test/scala/chiselTests/Direction.scala64
2 files changed, 47 insertions, 21 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/Aggregate.scala
index 4640cb0f..ba9afd5b 100644
--- a/chiselFrontend/src/main/scala/chisel3/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Aggregate.scala
@@ -156,7 +156,9 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int)
child.bind(ChildBinding(this), resolvedDirection)
}
- direction = sample_element.direction
+ // Since all children are the same, we can just use the sample_element rather than all children
+ // .get is safe because None means mixed directions, we only pass 1 so that's not possible
+ direction = ActualDirection.fromChildren(Set(sample_element.direction), resolvedDirection).get
}
// Note: the constructor takes a gen() function instead of a Seq to enforce
diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala
index 1e536a5a..b27eadd4 100644
--- a/src/test/scala/chiselTests/Direction.scala
+++ b/src/test/scala/chiselTests/Direction.scala
@@ -205,27 +205,37 @@ class DirectionSpec extends ChiselPropSpec with Matchers {
val b = Output(Bool())
}
+ val index = IO(Input(UInt(1.W)))
+
// Check all permutations of Vec and Flipped.
- val regularVec = IO(Vec(1, new MyBundle))
+ val regularVec = IO(Vec(2, new MyBundle))
regularVec <> DontCare
assert(DataMirror.directionOf(regularVec.head.a) == Direction.Input)
assert(DataMirror.directionOf(regularVec.head.b) == Direction.Output)
+ assert(DataMirror.directionOf(regularVec(index).a) == Direction.Input)
+ assert(DataMirror.directionOf(regularVec(index).b) == Direction.Output)
- val vecFlipped = IO(Vec(1, Flipped(new MyBundle)))
+ val vecFlipped = IO(Vec(2, Flipped(new MyBundle)))
vecFlipped <> DontCare
assert(DataMirror.directionOf(vecFlipped.head.a) == Direction.Output)
assert(DataMirror.directionOf(vecFlipped.head.b) == Direction.Input)
+ assert(DataMirror.directionOf(vecFlipped(index).a) == Direction.Output)
+ assert(DataMirror.directionOf(vecFlipped(index).b) == Direction.Input)
- val flippedVec = IO(Flipped(Vec(1, new MyBundle)))
+ val flippedVec = IO(Flipped(Vec(2, new MyBundle)))
flippedVec <> DontCare
assert(DataMirror.directionOf(flippedVec.head.a) == Direction.Output)
assert(DataMirror.directionOf(flippedVec.head.b) == Direction.Input)
+ assert(DataMirror.directionOf(flippedVec(index).a) == Direction.Output)
+ assert(DataMirror.directionOf(flippedVec(index).b) == Direction.Input)
// Flipped(Vec(Flipped())) should be equal to non-flipped.
- val flippedVecFlipped = IO(Flipped(Vec(1, Flipped(new MyBundle))))
+ val flippedVecFlipped = IO(Flipped(Vec(2, Flipped(new MyBundle))))
flippedVecFlipped <> DontCare
assert(DataMirror.directionOf(flippedVecFlipped.head.a) == Direction.Input)
assert(DataMirror.directionOf(flippedVecFlipped.head.b) == Direction.Output)
+ assert(DataMirror.directionOf(flippedVecFlipped(index).a) == Direction.Input)
+ assert(DataMirror.directionOf(flippedVecFlipped(index).b) == Direction.Output)
}
val elaborated = Driver.elaborate(() => new MyModule)
@@ -238,10 +248,10 @@ class DirectionSpec extends ChiselPropSpec with Matchers {
// Chisel Emitter formats spacing a little differently than the
// FIRRTL Emitter :-(
val s = o.replace("{flip a", "{ flip a")
- assert(s.contains("output regularVec : { flip a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("input vecFlipped : { flip a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("input flippedVec : { flip a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("output flippedVecFlipped : { flip a : UInt<1>, b : UInt<1>}[1]"))
+ assert(s.contains("output regularVec : { flip a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("input vecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("input flippedVec : { flip a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("output flippedVecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]"))
} }
}
@@ -252,35 +262,49 @@ class DirectionSpec extends ChiselPropSpec with Matchers {
val b = Output(Bool())
}
- val inputVec = IO(Vec(1, Input(new MyBundle)))
+ val index = IO(Input(UInt(1.W)))
+
+ val inputVec = IO(Vec(2, Input(new MyBundle)))
inputVec <> DontCare
assert(DataMirror.directionOf(inputVec.head.a) == Direction.Input)
assert(DataMirror.directionOf(inputVec.head.b) == Direction.Input)
+ assert(DataMirror.directionOf(inputVec(index).a) == Direction.Input)
+ assert(DataMirror.directionOf(inputVec(index).b) == Direction.Input)
- val vecInput = IO(Input(Vec(1, new MyBundle)))
+ val vecInput = IO(Input(Vec(2, new MyBundle)))
vecInput <> DontCare
assert(DataMirror.directionOf(vecInput.head.a) == Direction.Input)
assert(DataMirror.directionOf(vecInput.head.b) == Direction.Input)
+ assert(DataMirror.directionOf(vecInput(index).a) == Direction.Input)
+ assert(DataMirror.directionOf(vecInput(index).b) == Direction.Input)
- val vecInputFlipped = IO(Input(Vec(1, Flipped(new MyBundle))))
+ val vecInputFlipped = IO(Input(Vec(2, Flipped(new MyBundle))))
vecInputFlipped <> DontCare
assert(DataMirror.directionOf(vecInputFlipped.head.a) == Direction.Input)
assert(DataMirror.directionOf(vecInputFlipped.head.b) == Direction.Input)
+ assert(DataMirror.directionOf(vecInputFlipped(index).a) == Direction.Input)
+ assert(DataMirror.directionOf(vecInputFlipped(index).b) == Direction.Input)
- val outputVec = IO(Vec(1, Output(new MyBundle)))
+ val outputVec = IO(Vec(2, Output(new MyBundle)))
outputVec <> DontCare
assert(DataMirror.directionOf(outputVec.head.a) == Direction.Output)
assert(DataMirror.directionOf(outputVec.head.b) == Direction.Output)
+ assert(DataMirror.directionOf(outputVec(index).a) == Direction.Output)
+ assert(DataMirror.directionOf(outputVec(index).b) == Direction.Output)
- val vecOutput = IO(Output(Vec(1, new MyBundle)))
+ val vecOutput = IO(Output(Vec(2, new MyBundle)))
vecOutput <> DontCare
assert(DataMirror.directionOf(vecOutput.head.a) == Direction.Output)
assert(DataMirror.directionOf(vecOutput.head.b) == Direction.Output)
+ assert(DataMirror.directionOf(vecOutput(index).a) == Direction.Output)
+ assert(DataMirror.directionOf(vecOutput(index).b) == Direction.Output)
- val vecOutputFlipped = IO(Output(Vec(1, Flipped(new MyBundle))))
+ val vecOutputFlipped = IO(Output(Vec(2, Flipped(new MyBundle))))
vecOutputFlipped <> DontCare
assert(DataMirror.directionOf(vecOutputFlipped.head.a) == Direction.Output)
assert(DataMirror.directionOf(vecOutputFlipped.head.b) == Direction.Output)
+ assert(DataMirror.directionOf(vecOutputFlipped(index).a) == Direction.Output)
+ assert(DataMirror.directionOf(vecOutputFlipped(index).b) == Direction.Output)
}
val elaborated = Driver.elaborate(() => new MyModule)
@@ -293,12 +317,12 @@ class DirectionSpec extends ChiselPropSpec with Matchers {
// Chisel Emitter formats spacing a little differently than the
// FIRRTL Emitter :-(
val s = o.replace("{a", "{ a")
- assert(s.contains("input inputVec : { a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("input vecInput : { a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("input vecInputFlipped : { a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("output outputVec : { a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("output vecOutput : { a : UInt<1>, b : UInt<1>}[1]"))
- assert(s.contains("output vecOutputFlipped : { a : UInt<1>, b : UInt<1>}[1]"))
+ assert(s.contains("input inputVec : { a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("input vecInput : { a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("input vecInputFlipped : { a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("output outputVec : { a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("output vecOutput : { a : UInt<1>, b : UInt<1>}[2]"))
+ assert(s.contains("output vecOutputFlipped : { a : UInt<1>, b : UInt<1>}[2]"))
} }
}
}