diff options
| author | Edward Wang | 2019-04-10 00:16:48 -0700 |
|---|---|---|
| committer | edwardcwang | 2019-04-19 13:02:34 -0700 |
| commit | 32acdcf63ab74e7d47d7600f2211a72dd19280c3 (patch) | |
| tree | e4ff45be46e9353a06814aeecb9207284df388e8 /src/test/scala | |
| parent | fe5571d5218149ead6df36c82485bce8e31a223f (diff) | |
Fix wrong directionality for Vec(Flipped())
Create Chisel IR Port() in a way that Converter is happy with.
Also add more extensive test suite for future-proofing.
Close #1063
Diffstat (limited to 'src/test/scala')
| -rw-r--r-- | src/test/scala/chiselTests/Direction.scala | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala index 32e5a4fd..0b0807fd 100644 --- a/src/test/scala/chiselTests/Direction.scala +++ b/src/test/scala/chiselTests/Direction.scala @@ -127,7 +127,7 @@ class DirectionSpec extends ChiselPropSpec with Matchers { } } - import chisel3.experimental.{MultiIOModule, DataMirror, Direction} + import chisel3.experimental.{MultiIOModule, DataMirror, Direction, RawModule} import chisel3.core.SpecifiedDirection property("Directions should be preserved through cloning and binding of Bundles") { @@ -199,4 +199,108 @@ class DirectionSpec extends ChiselPropSpec with Matchers { } }.asInstanceOf[MultiIOModule]) // The cast works around weird reflection behavior (bug?) } + + property("Using Vec and Flipped together should calculate directions properly") { + class MyModule extends RawModule { + class MyBundle extends Bundle { + val a = Input(Bool()) + val b = Output(Bool()) + } + + // Check all permutations of Vec and Flipped. + val regularVec = IO(Vec(1, new MyBundle)) + regularVec <> DontCare + assert(DataMirror.directionOf(regularVec.head.a) == Direction.Input) + assert(DataMirror.directionOf(regularVec.head.b) == Direction.Output) + + val vecFlipped = IO(Vec(1, Flipped(new MyBundle))) + vecFlipped <> DontCare + assert(DataMirror.directionOf(vecFlipped.head.a) == Direction.Output) + assert(DataMirror.directionOf(vecFlipped.head.b) == Direction.Input) + + val flippedVec = IO(Flipped(Vec(1, new MyBundle))) + flippedVec <> DontCare + assert(DataMirror.directionOf(flippedVec.head.a) == Direction.Output) + assert(DataMirror.directionOf(flippedVec.head.b) == Direction.Input) + + // Flipped(Vec(Flipped())) should be equal to non-flipped. + val flippedVecFlipped = IO(Flipped(Vec(1, Flipped(new MyBundle)))) + flippedVecFlipped <> DontCare + assert(DataMirror.directionOf(flippedVecFlipped.head.a) == Direction.Input) + assert(DataMirror.directionOf(flippedVecFlipped.head.b) == Direction.Output) + } + + val elaborated = Driver.elaborate(() => new MyModule) + + val emitted: String = Driver.emit(elaborated) + val firrtl: String = Driver.toFirrtl(elaborated).serialize + + // Check that emitted directions are correct. + Seq(emitted, firrtl).foreach { o => { + // 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]")) + } } + } + + property("Vec with Input/Output should calculate directions properly") { + class MyModule extends RawModule { + class MyBundle extends Bundle { + val a = Input(Bool()) + val b = Output(Bool()) + } + + val inputVec = IO(Vec(1, Input(new MyBundle))) + inputVec <> DontCare + assert(DataMirror.directionOf(inputVec.head.a) == Direction.Input) + assert(DataMirror.directionOf(inputVec.head.b) == Direction.Input) + + val vecInput = IO(Input(Vec(1, new MyBundle))) + vecInput <> DontCare + assert(DataMirror.directionOf(vecInput.head.a) == Direction.Input) + assert(DataMirror.directionOf(vecInput.head.b) == Direction.Input) + + val vecInputFlipped = IO(Input(Vec(1, Flipped(new MyBundle)))) + vecInputFlipped <> DontCare + assert(DataMirror.directionOf(vecInputFlipped.head.a) == Direction.Input) + assert(DataMirror.directionOf(vecInputFlipped.head.b) == Direction.Input) + + val outputVec = IO(Vec(1, Output(new MyBundle))) + outputVec <> DontCare + assert(DataMirror.directionOf(outputVec.head.a) == Direction.Output) + assert(DataMirror.directionOf(outputVec.head.b) == Direction.Output) + + val vecOutput = IO(Output(Vec(1, new MyBundle))) + vecOutput <> DontCare + assert(DataMirror.directionOf(vecOutput.head.a) == Direction.Output) + assert(DataMirror.directionOf(vecOutput.head.b) == Direction.Output) + + val vecOutputFlipped = IO(Output(Vec(1, Flipped(new MyBundle)))) + vecOutputFlipped <> DontCare + assert(DataMirror.directionOf(vecOutputFlipped.head.a) == Direction.Output) + assert(DataMirror.directionOf(vecOutputFlipped.head.b) == Direction.Output) + } + + val elaborated = Driver.elaborate(() => new MyModule) + + val emitted: String = Driver.emit(elaborated) + val firrtl: String = Driver.toFirrtl(elaborated).serialize + + // Check that emitted directions are correct. + Seq(emitted, firrtl).foreach { o => { + // 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]")) + } } + } } |
