From 5a49173b7badcd4fda1146a431b4221ea55692b7 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Mon, 8 Jul 2024 17:51:23 -0700 Subject: [PATCH 1/2] Use :<>= in VecInit methods instead of := or <> (#4248) Previously, VecInit would try to "intelligently" select := or <> depending on if the type is bidirectional. :<>= has the desirable behavior here for both passive and bidirectional types. It also has the advantage over <> of handling internal wires. (cherry picked from commit 255d3d4d6ee8bc71a95f894921cef36c728d35c1) --- core/src/main/scala/chisel3/Aggregate.scala | 35 ++++----------------- src/test/scala/chiselTests/Vec.scala | 15 +++++++++ 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 2043ae749a3..e9f718e89af 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -633,26 +633,6 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend object VecInit extends SourceInfoDoc { - /** Gets the correct connect operation (directed hardware assign or bulk connect) for element in Vec. - */ - private def getConnectOpFromDirectionality[T <: Data]( - proto: T - )( - implicit sourceInfo: SourceInfo - ): (T, T) => Unit = proto.direction match { - case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified => - // When internal wires are involved, driver / sink must be specified explicitly, otherwise - // the system is unable to infer which is driver / sink - (x, y) => x := y - case ActualDirection.Bidirectional(_) => - // For bidirectional, must issue a bulk connect so subelements are resolved correctly. - // Bulk connecting two wires may not succeed because Chisel frontend does not infer - // directions. - (x, y) => x <> y - case ActualDirection.Empty => - (x, y) => x <> y - } - /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]] * nodes. * @@ -678,10 +658,9 @@ object VecInit extends SourceInfoDoc { elts.foreach(requireIsHardware(_, "vec element")) val vec = Wire(Vec(elts.length, cloneSupertype(elts, "Vec"))) - val op = getConnectOpFromDirectionality(vec.head) - (vec.zip(elts)).foreach { x => - op(x._1, x._2) + for ((lhs, rhs) <- vec.zip(elts)) { + lhs :<>= rhs } vec } @@ -747,12 +726,11 @@ object VecInit extends SourceInfoDoc { val tpe = cloneSupertype(flatElts, "Vec.tabulate") val myVec = Wire(Vec(n, Vec(m, tpe))) - val op = getConnectOpFromDirectionality(myVec.head.head) for { (xs1D, ys1D) <- myVec.zip(elts) - (x, y) <- xs1D.zip(ys1D) + (lhs, rhs) <- xs1D.zip(ys1D) } { - op(x, y) + lhs :<>= rhs } myVec } @@ -787,14 +765,13 @@ object VecInit extends SourceInfoDoc { val tpe = cloneSupertype(flatElts, "Vec.tabulate") val myVec = Wire(Vec(n, Vec(m, Vec(p, tpe)))) - val op = getConnectOpFromDirectionality(myVec.head.head.head) for { (xs2D, ys2D) <- myVec.zip(elts) (xs1D, ys1D) <- xs2D.zip(ys2D) - (x, y) <- xs1D.zip(ys1D) + (lhs, rhs) <- xs1D.zip(ys1D) } { - op(x, y) + lhs :<>= rhs } myVec diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index 3fff8bb0843..c6847223f66 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -285,6 +285,21 @@ class VecSpec extends ChiselPropSpec with Utils { } } + property("VecInit should work for Bundle that mixes Output and unspecified UInts") { + class MyBundle extends Bundle { + val a = Output(UInt(8.W)) + val b = UInt(8.W) + } + val chirrtl = emitCHIRRTL(new RawModule { + val w = VecInit(Seq.fill(2)(0.U.asTypeOf(new MyBundle))) + }) + chirrtl should include("wire w : { a : UInt<8>, b : UInt<8>}[2]") + chirrtl should include("connect w[0].b, UInt<8>(0h0)") + chirrtl should include("connect w[0].a, UInt<8>(0h0)") + chirrtl should include("connect w[1].b, UInt<8>(0h0)") + chirrtl should include("connect w[1].a, UInt<8>(0h0)") + } + property("Infering widths on huge Vecs should not cause a stack overflow") { ChiselStage.emitSystemVerilog(new HugeVecTester(10000)) } From 08034a55f3003381e989aa5aac6017a91a77b198 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Tue, 9 Jul 2024 15:39:33 -0700 Subject: [PATCH 2/2] Fix test for 6.x --- src/test/scala/chiselTests/Vec.scala | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index c6847223f66..f1ad5ae4433 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -293,11 +293,17 @@ class VecSpec extends ChiselPropSpec with Utils { val chirrtl = emitCHIRRTL(new RawModule { val w = VecInit(Seq.fill(2)(0.U.asTypeOf(new MyBundle))) }) + chirrtl should include("wire _w_WIRE : { a : UInt<8>, b : UInt<8>}") + chirrtl should include("connect _w_WIRE.b, UInt<8>(0h0)") + chirrtl should include("connect _w_WIRE.a, UInt<8>(0h0)") + chirrtl should include("wire _w_WIRE_1 : { a : UInt<8>, b : UInt<8>}") + chirrtl should include("connect _w_WIRE_1.b, UInt<8>(0h0)") + chirrtl should include("connect _w_WIRE_1.a, UInt<8>(0h0)") chirrtl should include("wire w : { a : UInt<8>, b : UInt<8>}[2]") - chirrtl should include("connect w[0].b, UInt<8>(0h0)") - chirrtl should include("connect w[0].a, UInt<8>(0h0)") - chirrtl should include("connect w[1].b, UInt<8>(0h0)") - chirrtl should include("connect w[1].a, UInt<8>(0h0)") + chirrtl should include("connect w[0].b, _w_WIRE.b") + chirrtl should include("connect w[0].a, _w_WIRE.a") + chirrtl should include("connect w[1].b, _w_WIRE_1.b") + chirrtl should include("connect w[1].a, _w_WIRE_1.a") } property("Infering widths on huge Vecs should not cause a stack overflow") {