Skip to content

Commit

Permalink
Allow DataView of Reset <=> [UInt<1>, AsyncReset] (#3181)
Browse files Browse the repository at this point in the history
Change what DataView allows in its type checking to enable Reset to be
viewed as either a UInt<1> or an AsyncReset.  This enables more flexible
DataViews which match already allowable Chisel and FIRRTL connection
semantics.

Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
  • Loading branch information
seldridge committed May 5, 2023
1 parent 86ec932 commit 44ce96c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
16 changes: 13 additions & 3 deletions core/src/main/scala/chisel3/experimental/dataview/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
34 changes: 34 additions & 0 deletions src/test/scala/chiselTests/experimental/DataView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down

0 comments on commit 44ce96c

Please sign in to comment.