Unifying Chisel._ and chisel3._ connection semantics
Type of issue: Feature Request
Is your feature request related to a problem? Please describe.
Background: Chisel._ vs chisel3._ directionality
In Chisel._, IO has an implicit output direction, and Flipped is used for two things:
- Define relative direction of a field with respect to its parent bundle
- To change the implicit output to an implicit input of IO
val io = IO(new Bundle { // implicit output
val x = Flipped(UInt()) // x is flipped relative to bundle, so it is an input
val y = UInt() // y is aligned relative to bundle, so it is an output
})
You can declare an input port using the (2) kind of Flipped:
val io = IO(Flipped(new Bundle { // implicit input
val x = Flipped(UInt()) // x is flipped relative to bundle, so it is an output
val y = UInt() // y is aligned relative to bundle, so it is an input
}))
In chisel3, IO does not have an implicit direction, but Input and Output are specified on types, which coerce all subfields of the type to the same direction. Flipped inverts the absolute direction so Input -> Output and Output -> Input.
val io = IO(new Bundle { // no implicit direction
val x = Input(UInt()) // x is an input
val y = Output(UInt()) // y is an output
}))
You can switch directions with Flipped:
val io = IO(Flipped(new Bundle { // Swap all absolute directions
val x = Input(UInt()) // x is flipped so it is an output
val y = Output(UInt()) // y is flipped so it is an input
})))
Describe the solution you'd like
Unifying directionality with new primitives
Both mechanisms of describing field directions can be unified with the following (conceptual) primitives:
-
Flipped: a field's relative direction is reversed with respect to its parent bundle -
Aligned: a field's relative direction is the same with respect to its parent bundle (is implicit) -
Outgoing: an IO whose implicit direction is output -
Incoming: an IO whose implicit direction is input -
stripFlipsOf: a type-generator that aligns all subfields, recursively -
reverseFlipsOf: a type-generator that flips all subfields, recursively
Expressing Chisel._ semantics:
-
IO(new Bundle))becomesOutgoing(new Bundle) -
IO(Flipped(new Bundle))becomesIncoming(new Bundle); note thatOutgoing(reverseFlipsOf(new Bundle))is the same, but I think it makes sense to haveIncomingas well. -
new Bundle { val x = UInt() }isnew Bundle { val x = Aligned(UInt()) }, or unchanged asAlignedis implicit -
new Bundle { val x = Flipped(UInt()) }is unchanged
Expressing chisel3._ semantics:
-
IO(new Bundle))becomesOutgoing(new Bundle) -
IO(Flipped(new Bundle))becomesIncoming(new Bundle) -
new Bundle { val x = Output(UInt()) }isnew Bundle { val x = Aligned(stripFlipsOf(UInt())) } -
new Bundle { val x = Input(UInt()) }isnew Bundle { val x = Flipped(stripFlipsOf(UInt())) }
Describe alternatives you've considered
keeping things the same as they are.
Additional context
What is the use case for implementing this feature?
Being able to unify and improve LegacyChisel vs chisel3 connection semantics to overall simplify the code base.
@azidar I grabbed the great writeup from #2634 to an issue since it seems like we might have various PRs that fall into this issue heading
i was thinking about this recently, does it make sense to have stripFlipsOf be actually an opaque type? so that the scala type is actually StrippedFlipsOf[BidirType]?
to me this maybe makes it more sense for things like:
a: A :#= b: A
maybe makes more sense explicitly as:
a: StrippedFlipsOf[A] :#= b: A
I'm not sure we can do it that way do to the prevalence of val x: DecoupledIO[UInt] = Output(new DecoupledIO(UInt(1.W))), which strips the flips, but the return scala type is still DecoupledIO[UInt]. I think your proposal would change the scala type of all return values from Input and Output.
scala type of all return values from Input and Output
Right, I guess that's what I'm explicitly saying. Do we want them to have the same type, and if so, why? Given that we could define :#= on the types that we explicitly mean. What is the other reason for them having the same type?
Gotcha. Yeah so maybe in the long term its a better way to have stripflipsof