diff options
Diffstat (limited to 'src/test/scala/chiselTests/Direction.scala')
| -rw-r--r-- | src/test/scala/chiselTests/Direction.scala | 443 |
1 files changed, 0 insertions, 443 deletions
diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala deleted file mode 100644 index ddbd99d2..00000000 --- a/src/test/scala/chiselTests/Direction.scala +++ /dev/null @@ -1,443 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package chiselTests - -import org.scalatest._ -import chisel3._ -import chisel3.experimental.OpaqueType -import chisel3.stage.ChiselStage -import org.scalatest.matchers.should.Matchers - -import scala.collection.immutable.SeqMap - -class DirectionedBundle extends Bundle { - val in = Input(UInt(32.W)) - val out = Output(UInt(32.W)) -} - -class DirectionHaver extends Module { - val io = IO(new Bundle { - val in = Input(UInt(32.W)) - val out = Output(UInt(32.W)) - val inBundle = Input(new DirectionedBundle) // should override elements - val outBundle = Output(new DirectionedBundle) // should override elements - }) -} - -class GoodDirection extends DirectionHaver { - io.out := 0.U - io.outBundle.in := 0.U - io.outBundle.out := 0.U -} - -class BadDirection extends DirectionHaver { - io.in := 0.U -} - -class BadSubDirection extends DirectionHaver { - io.inBundle.out := 0.U -} - -class TopDirectionOutput extends Module { - val io = IO(Output(new DirectionedBundle)) - io.in := 42.U - io.out := 117.U -} - -class DirectionSpec extends ChiselPropSpec with Matchers with Utils { - - //TODO: In Chisel3 these are actually FIRRTL errors. Remove from tests? - - property("Outputs should be assignable") { - ChiselStage.elaborate(new GoodDirection) - } - - property("Inputs should not be assignable") { - a[Exception] should be thrownBy extractCause[Exception] { - ChiselStage.elaborate(new BadDirection) - } - a[Exception] should be thrownBy extractCause[Exception] { - ChiselStage.elaborate(new BadSubDirection) - } - } - - property("Top-level forced outputs should be assignable") { - ChiselStage.elaborate(new TopDirectionOutput) - } - - property("Empty Vecs with directioned sample_element should not cause direction errors") { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = Vec(0, Output(UInt(8.W))) - }) - }) - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = Flipped(Vec(0, Output(UInt(8.W)))) - }) - }) - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = Output(Vec(0, UInt(8.W))) - }) - }) - } - - property( - "Empty Vecs with no direction on the sample_element should not cause direction errors, as Chisel and chisel3 directions are merged" - ) { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = Vec(0, UInt(8.W)) - }) - }) - } - - property("Empty Bundles should not cause direction errors") { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = new Bundle {} - }) - }) - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = Flipped(new Bundle {}) - }) - }) - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = new Bundle { - val y = if (false) Some(Input(UInt(8.W))) else None - } - }) - }) - } - - property( - "Explicitly directioned but empty Bundles should not cause direction errors because Chisel and chisel3 directionality are merged" - ) { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = UInt(8.W) - val x = Input(new Bundle {}) - }) - }) - } - - import chisel3.experimental.{DataMirror, Direction} - - property("Directions should be preserved through cloning and binding of Bundles") { - ChiselStage.elaborate(new Module { - class MyBundle extends Bundle { - val foo = Input(UInt(8.W)) - val bar = Output(UInt(8.W)) - } - class MyOuterBundle extends Bundle { - val fizz = new MyBundle - val buzz = Flipped(new MyBundle) - } - val a = new MyOuterBundle - val b = IO(a) - val specifiedDirs = Seq( - a.fizz.foo -> SpecifiedDirection.Input, - a.fizz.bar -> SpecifiedDirection.Output, - a.fizz -> SpecifiedDirection.Unspecified, - a.buzz.foo -> SpecifiedDirection.Input, - a.buzz.bar -> SpecifiedDirection.Output, - a.buzz -> SpecifiedDirection.Flip - ) - val actualDirs = Seq( - b.fizz.foo -> Direction.Input, - b.fizz.bar -> Direction.Output, - b.fizz -> Direction.Bidirectional(Direction.Default), - b.buzz.foo -> Direction.Output, - b.buzz.bar -> Direction.Input, - b.buzz -> Direction.Bidirectional(Direction.Flipped) - ) - for ((data, dir) <- specifiedDirs) { - DataMirror.specifiedDirectionOf(data) shouldBe (dir) - } - for ((data, dir) <- actualDirs) { - DataMirror.directionOf(data) shouldBe (dir) - } - }.asInstanceOf[Module]) // The cast works around weird reflection behavior (bug?) - } - - property("Directions should be preserved through cloning and binding of Vecs") { - ChiselStage.elaborate(new Module { - val a = Vec(1, Input(UInt(8.W))) - val b = Vec(1, a) - val c = Vec(1, Flipped(a)) - val io0 = IO(b) - val io1 = IO(c) - val specifiedDirs = Seq( - a(0) -> SpecifiedDirection.Input, - b(0)(0) -> SpecifiedDirection.Input, - a -> SpecifiedDirection.Unspecified, - b -> SpecifiedDirection.Unspecified, - c(0) -> SpecifiedDirection.Flip, - c(0)(0) -> SpecifiedDirection.Input, - c -> SpecifiedDirection.Unspecified - ) - val actualDirs = Seq( - io0(0)(0) -> Direction.Input, - io0(0) -> Direction.Input, - io0 -> Direction.Input, - io1(0)(0) -> Direction.Output, - io1(0) -> Direction.Output, - io1 -> Direction.Output - ) - for ((data, dir) <- specifiedDirs) { - DataMirror.specifiedDirectionOf(data) shouldBe (dir) - } - for ((data, dir) <- actualDirs) { - DataMirror.directionOf(data) shouldBe (dir) - } - }.asInstanceOf[Module]) // 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()) - } - - val index = IO(Input(UInt(1.W))) - - // Check all permutations of Vec and Flipped. - 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(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(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(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 emitted: String = ChiselStage.emitChirrtl(new MyModule) - val firrtl: String = ChiselStage.convert(new MyModule).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>}[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]")) - } - } - } - - 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 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(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(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(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(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(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 emitted: String = ChiselStage.emitChirrtl(new MyModule) - val firrtl: String = ChiselStage.convert(new MyModule).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>}[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]")) - } - } - } - property("Can now describe a Decoupled bundle using Flipped, not Input/Output in chisel3") { - class Decoupled extends Bundle { - val bits = UInt(3.W) - val valid = Bool() - val ready = Flipped(Bool()) - } - class MyModule extends RawModule { - val incoming = IO(Flipped(new Decoupled)) - val outgoing = IO(new Decoupled) - - outgoing <> incoming - } - - val emitted: String = ChiselStage.emitChirrtl(new MyModule) - - // Check that emitted directions are correct. - assert(emitted.contains("input incoming : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}")) - assert(emitted.contains("output outgoing : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}")) - assert(emitted.contains("outgoing <= incoming")) - } - property("Can now mix Input/Output and Flipped within the same bundle") { - class Decoupled extends Bundle { - val bits = UInt(3.W) - val valid = Bool() - val ready = Flipped(Bool()) - } - class DecoupledAndMonitor extends Bundle { - val producer = new Decoupled() - val consumer = Flipped(new Decoupled()) - val monitor = Input(new Decoupled()) // Same as Flipped(stripFlipsIn(..)) - val driver = Output(new Decoupled()) // Same as stripFlipsIn(..) - } - class MyModule extends RawModule { - val io = IO(Flipped(new DecoupledAndMonitor())) - io.consumer <> io.producer - io.monitor.bits := io.driver.bits - io.monitor.valid := io.driver.valid - io.monitor.ready := io.driver.ready - } - - val emitted: String = ChiselStage.emitChirrtl(new MyModule) - - assert( - emitted.contains( - "input io : { producer : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}, flip consumer : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}, flip monitor : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}, driver : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}}" - ) - ) - assert(emitted.contains("io.consumer <= io.producer")) - assert(emitted.contains("io.monitor.bits <= io.driver.bits")) - assert(emitted.contains("io.monitor.valid <= io.driver.valid")) - assert(emitted.contains("io.monitor.ready <= io.driver.ready")) - } - property("Bugfix: marking Vec fields with mixed directionality as Output/Input clears inner directions") { - class Decoupled extends Bundle { - val bits = UInt(3.W) - val valid = Bool() - val ready = Flipped(Bool()) - } - class Coercing extends Bundle { - val source = Output(Vec(1, new Decoupled())) - val sink = Input(Vec(1, new Decoupled())) - } - class MyModule extends RawModule { - val io = IO(new Coercing()) - val source = IO(Output(Vec(1, new Decoupled()))) - val sink = IO(Input(Vec(1, new Decoupled()))) - } - - val emitted: String = ChiselStage.emitChirrtl(new MyModule) - - assert( - emitted.contains( - "output io : { source : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1], flip sink : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1]}" - ) - ) - assert( - emitted.contains( - "output source : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1]" - ) - ) - assert( - emitted.contains( - "input sink : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1]" - ) - ) - } - property("Bugfix: clearing all flips inside an opaque type") { - - class Decoupled extends Bundle { - val bits = UInt(3.W) - val valid = Bool() - val ready = Flipped(Bool()) - } - class MyOpaqueType extends Record with OpaqueType { - val k = new Decoupled() - val elements = SeqMap("" -> k) - override def cloneType: this.type = (new MyOpaqueType).asInstanceOf[this.type] - } - class MyModule extends RawModule { - val w = Wire(new MyOpaqueType()) - } - - val emitted: String = ChiselStage.emitChirrtl(new MyModule) - - assert( - emitted.contains( - "wire w : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}" - ) - ) - } -} |
