Skip to content

Commit

Permalink
Merge pull request #2339 from chipsalliance/scaladoc-fixchisel3
Browse files Browse the repository at this point in the history
FixChisel3: Add some commentary to scaladoc
  • Loading branch information
mwachs5 committed May 17, 2020
2 parents 97117fa + 6c8a5d9 commit 16d49a7
Showing 1 changed file with 37 additions and 5 deletions.
42 changes: 37 additions & 5 deletions src/main/scala/util/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,23 +234,55 @@ package object util {
map.view.map({ case (k, vs) => k -> vs.toList }).toList
}

/** provides operators useful for working with bidirectional [[Bundle]]s
*
* In terms of [[Flipped]] with a producer 'p' and 'consumer' c:
* c :<= p // means drive all unflipped fields of 'c' from 'p' (e.g.: c.valid := p.valid)
* c :=> p // means drive all flipped fields of 'p' from 'c' (e.g.: `p.ready := c.ready`)
* c :<> p // do both of the above
* p :<> c // do both of the above, but you'll probably get a Flow error later.
*
* This utility class is needed because in [[chisel3]]:
* c := p // only works if there are no directions on fields.
* c <> p // only works if one of those is an [[IO]] (not a [[Wire]]).
*
* Compared with [[chisel3]] operators:
* c <> p is an 'actual-direction'-inferred 'c :<> p' or 'p :<> c'
* c := p is equivalent to 'c :<= p' + 'p :=> c'. In other words, drive ALL fields of 'c' from 'p' regardless of their direction.
*
* Contrast this with 'c :<> p' which will connect a ready-valid producer
* 'p' to a consumer 'c'.
* If you flip this to 'p :<> c', it works the way you would expect (flipping the role of producer/consumer).
* This is how Chisel._ (compatability mode) and firrtl work.
* Some find that ':<>' has superior readability (even if the direction can be inferred from an IO),
* because it clearly states the intended producer/consumer relationship.
* You will get an appropriate error if you connected it the wrong way
* (usually because you got the IO direction wrong) instead of silently succeeding.
*
* What if you want to connect all of the signals (e.g. ready/valid/bits)
* from producer 'p' to a monitor 'm'?
* For example in order to tap the connection to monitor traffic on an existing connection.
* In that case you can do 'm :<= p' and 'p :=> m'.
*/
implicit class EnhancedChisel3Assign[T <: Data](val x: T) extends AnyVal {
// Assign all output fields of x from y; note that the actual direction of x is irrelevant
/** Assign all output fields of x from y; note that the actual direction of x is irrelevant */
def :<= (y: T): Unit = FixChisel3.assignL(x, y)
// Assign all input fields of y from x; note that the actual direction of y is irrelevant
/** Assign all input fields of y from x; note that the actual direction of y is irrelevant */
def :=> (y: T): Unit = FixChisel3.assignR(x, y)
// Wire-friendly bulk connect
/** Bulk connect which will work between two [[Wire]]s (in addition to between [[IO]]s) */
def :<> (y: T): Unit = {
FixChisel3.assignL(x, y)
FixChisel3.assignR(x, y)
}
// x <> y is an 'actual-direction'-inferred 'x :<> y' or 'y :<> x'
// x := y is equivalent to 'x :<= y' + 'y :=> x'


// Versions of the operators that use the type from the RHS
// y :<=: x -> x.:<=:(y) -> y :<= x -> FixChisel3.assignL(y, x)
/** version of the :<= operator that uses the type from the RHS */
def :<=: (y: T): Unit = { FixChisel3.assignL(y, x) }
/** version of the :=> operator that uses the type from the RHS */
def :>=: (y: T): Unit = { FixChisel3.assignR(y, x) }
/** version of the :<> operator that uses the type from the RHS */
def :<>: (y: T): Unit = {
FixChisel3.assignL(y, x)
FixChisel3.assignR(y, x)
Expand Down

0 comments on commit 16d49a7

Please sign in to comment.