diff --git a/core/src/main/scala/chisel3/experimental/dataview/package.scala b/core/src/main/scala/chisel3/experimental/dataview/package.scala index 072ce6c6446..52c5bfdadf1 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/package.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/package.scala @@ -103,9 +103,19 @@ package object dataview { val tex = unfoldView(te).find(targetContains).getOrElse(err("Target", te)) val vex = unfoldView(ve).find(viewFieldLookup.contains).getOrElse(err("View", ve)) - if (tex.getClass != vex.getClass) { - val fieldName = viewFieldName(vex) - throw InvalidViewException(s"Field $fieldName specified as view of non-type-equivalent value $tex") + (tex, vex) match { + /* Allow views where the types are equal. */ + case (a, b) if a.getClass == b.getClass => + /* allow bool <=> reset views. */ + case (a: Bool, _: Reset) => + case (_: Reset, a: Bool) => + /* Allow AsyncReset <=> Reset views. */ + case (a: AsyncReset, _: Reset) => + case (_: Reset, a: AsyncReset) => + /* All other views produce a runtime error. */ + case _ => + val fieldName = viewFieldName(vex) + throw InvalidViewException(s"Field $fieldName specified as view of non-type-equivalent value $tex") } // View width must be unknown or match target width if (vex.widthKnown && vex.width != tex.width) { diff --git a/src/test/scala/chiselTests/experimental/DataView.scala b/src/test/scala/chiselTests/experimental/DataView.scala index a443fafe410..6b1d7785bed 100644 --- a/src/test/scala/chiselTests/experimental/DataView.scala +++ b/src/test/scala/chiselTests/experimental/DataView.scala @@ -546,6 +546,40 @@ class DataViewSpec extends ChiselFlatSpec { chirrtl should include("dataOut <= vec[addrReg]") } + it should "allow views between reset types" in { + class A extends Bundle { + val bool = Bool() + val asyncreset = AsyncReset() + } + + class B extends Bundle { + val reset_0 = Reset() + val reset_1 = Reset() + } + + class Foo extends RawModule { + val a = Wire(new A) + val b = Wire(new B) + + implicit val view = DataView[A, B]( + _ => new B, + _.bool -> _.reset_0, + _.asyncreset -> _.reset_1 + ) + + a.viewAs[B] := b + } + + (ChiselStage + .emitCHIRRTL(new Foo, Array("--full-stacktrace")) + .split('\n') + .map(_.takeWhile(_ != '@')) + .map(_.trim) should contain).allOf( + "a.bool <= b.reset_0", + "a.asyncreset <= b.reset_1" + ) + } + it should "error if you try to dynamically index a Vec view that does not correspond to a Vec target" in { class MyModule extends Module { val inA, inB = IO(Input(UInt(8.W)))