diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala index cdd897ffc98..76a8bc956a1 100644 --- a/core/src/main/scala/chisel3/Data.scala +++ b/core/src/main/scala/chisel3/Data.scala @@ -814,7 +814,9 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { def do_asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo): T = { val thatCloned = Wire(that.cloneTypeFull) thatCloned.connectFromBits(this.asUInt) - thatCloned + thatCloned.viewAsReadOnlyDeprecated(siteInfo => + Warning(WarningID.AsTypeOfReadOnly, s"Return values of asTypeOf will soon be read-only")(siteInfo) + ) } /** Assigns this node from Bits type. Internal implementation for asTypeOf. diff --git a/core/src/main/scala/chisel3/internal/Warning.scala b/core/src/main/scala/chisel3/internal/Warning.scala index bcd60ec0e5f..a08dd595bc9 100644 --- a/core/src/main/scala/chisel3/internal/Warning.scala +++ b/core/src/main/scala/chisel3/internal/Warning.scala @@ -20,6 +20,7 @@ private[chisel3] object WarningID extends Enumeration { val DynamicIndexTooNarrow = Value(5) val ExtractFromVecSizeZero = Value(6) val BundleLiteralValueTooWide = Value(7) + val AsTypeOfReadOnly = Value(8) } import WarningID.WarningID diff --git a/docs/src/explanations/warnings.md b/docs/src/explanations/warnings.md index 87a1beddbc8..fa8f6446df7 100644 --- a/docs/src/explanations/warnings.md +++ b/docs/src/explanations/warnings.md @@ -149,4 +149,29 @@ It can be fixed by removing the indexing operation for the size zero `Vec` (perh This warning occurs when creating a [Bundle Literal](../appendix/experimental-features#bundle-literals) where the literal value for a field is wider than the Bundle field's width. It can be fixed by reducing the width of the literal (perhaps choosing a different value if it is impossible to encode the value in the -field's width). \ No newline at end of file +field's width). + +### [W008] Return values of asTypeOf will soon be read-only + +This warning indicates that the result of a call to `.asTypeOf(_)` is being used as the destination for a connection. +It can be fixed by instantiating a wire. + +For example, given the following: +```scala mdoc:compile-only +class MyBundle extends Bundle { + val foo = UInt(8.W) + val bar = UInt(8.W) +} +val x = 0.U.asTypeOf(new MyBundle) +x.bar := 123.U +``` + +The warning can be fixed by inserting a wire: +```scala mdoc:compile-only +class MyBundle extends Bundle { + val foo = UInt(8.W) + val bar = UInt(8.W) +} +val x = WireInit(0.U.asTypeOf(new MyBundle)) +x.bar := 123.U +``` diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index 3fff8bb0843..9606e9a1e10 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -319,9 +319,9 @@ class VecSpec extends ChiselPropSpec with Utils { }) chirrtl should include("output io : { foo : UInt<1>, bar : UInt<1>[0]}") - chirrtl should include("wire zero : { foo : UInt<1>, bar : UInt<1>[0]}") - chirrtl should include("connect zero.foo, UInt<1>(0h0)") - chirrtl should include("connect io, zero") + chirrtl should include("wire _zero_WIRE : { foo : UInt<1>, bar : UInt<1>[0]}") + chirrtl should include("connect _zero_WIRE.foo, UInt<1>(0h0)") + chirrtl should include("connect io, _zero_WIRE") chirrtl should include("wire w : UInt<1>[0]") chirrtl should include("connect w, m.io.bar") } diff --git a/src/test/scala/chiselTests/stage/WarningConfigurationSpec.scala b/src/test/scala/chiselTests/stage/WarningConfigurationSpec.scala index eb491f44b3a..eb3b7f5f006 100644 --- a/src/test/scala/chiselTests/stage/WarningConfigurationSpec.scala +++ b/src/test/scala/chiselTests/stage/WarningConfigurationSpec.scala @@ -56,6 +56,14 @@ object WarningConfigurationSpec { val idx = IO(Input(UInt(8.W))) in(idx) } + class MyBundle extends Bundle { + val foo = UInt(8.W) + } + class AsTypeOfReadOnly extends RawModule { + val in = IO(Input(UInt(8.W))) + val bundle = in.asTypeOf(new MyBundle) + bundle.foo := 0.U + } } class WarningConfigurationSpec extends AnyFunSpec with Matchers with chiselTests.Utils { @@ -371,5 +379,11 @@ class WarningConfigurationSpec extends AnyFunSpec with Matchers with chiselTests val e = the[Exception] thrownBy ChiselStage.emitCHIRRTL(new ExtractFromVecSizeZero, args) e.getMessage should include("[W006] Cannot extract from Vec of size 0") } + + it("should number AsTypeOfReadOnly as 8") { + val args = Array("--warn-conf", "id=8:e,any:s", "--throw-on-first-error") + val e = the[Exception] thrownBy ChiselStage.emitCHIRRTL(new AsTypeOfReadOnly, args) + e.getMessage should include("[W008] Return values of asTypeOf will soon be read-only") + } } }