From be4463a7756351dcab09ba3f576f5e3687fb0ebf Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Thu, 10 Nov 2022 20:03:45 +0000 Subject: Unify Chisel2 and chisel3 directionality (backport #2634) (#2837) * Unify Chisel2 and chisel3 directionality (#2634) Co-authored-by: Jack Koenig (cherry picked from commit 1aea4ef96466cbe08150d20c85c88b81e4e4f80f) # Conflicts: # core/src/main/scala/chisel3/Aggregate.scala # core/src/main/scala/chisel3/Module.scala # src/test/scala/chiselTests/Direction.scala * fix up backport * fix up backport * clean up diff * make test order like it was on master Co-authored-by: Adam Izraelevitz Co-authored-by: Megan Wachs --- src/test/scala/chiselTests/Direction.scala | 84 ++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala index 642a507c..ddbd99d2 100644 --- a/src/test/scala/chiselTests/Direction.scala +++ b/src/test/scala/chiselTests/Direction.scala @@ -86,15 +86,15 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { }) } - property("Empty Vecs with no direction on the sample_element *should* cause direction errors") { - an[Exception] should be thrownBy extractCause[Exception] { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = Input(UInt(8.W)) - val x = 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") { @@ -120,15 +120,15 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { }) } - property("Explicitly directioned but empty Bundles should cause direction errors") { - an[Exception] should be thrownBy extractCause[Exception] { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val foo = UInt(8.W) - val x = Input(new Bundle {}) - }) + 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} @@ -330,6 +330,58 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { } } } + 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) -- cgit v1.2.3