Add .asProducer, .asConsumer and deprecated forms#5413
Conversation
AI-assisted-by: Claude Code (Claude Opus 4.8)
|
Future work: use this (the deprecated form) on methods like |
| But because the returned value is just an ordinary `Wire`, nothing stops a caller from accidentally driving `valid` or `bits` themselves — overwriting what the library already drove and silently breaking the design. | ||
|
|
||
| `.asProducer` and `.asConsumer` let the library encode that intent into the value it returns. | ||
| They tag a component with its intended role, which does two things: |
There was a problem hiding this comment.
what is a 'component'? Is this a term we use in this doc otherwise?
Specifically, can i tag only asProducer and asConsumer on some deeply nested members of an aggregate?
There was a problem hiding this comment.
nvm i guess we did formally define component, and we seem to use the word member interchangeably with field.
So given that, is it true that i can only call asProducer/asConsumer on the 'root' of the component (the root Wire(...), IO(...) thing?
There was a problem hiding this comment.
, is it true that i can only call asProducer/asConsumer on the 'root' of the component (the root Wire(...), IO(...) thing?
Nope, so component is probably the wrong word. Maybe just Data?
| Recall from [Alignment: Flipped vs Aligned](#alignment-flipped-vs-aligned) that a producer drives its aligned members and is driven on its flipped members (and vice versa for a consumer). | ||
| Accordingly: | ||
|
|
||
| * `.asProducer` marks the **aligned** members read-only (a producer should never have its outputs driven), leaving flipped members writable. It may only appear on the **right-hand side**. |
There was a problem hiding this comment.
i am not sure about this "on the right-hand-side". Of what, the :<>= operator? Any of the :<>=, :>=, :<= operators?
There was a problem hiding this comment.
Of any of the of the connectable operators, yeah. It's not enforced on <>, maybe it should be.
There was a problem hiding this comment.
I'd like to deprecate it 🙂
| Flipped fields remain writable, so `Wire(Decoupled(UInt(8.W))).asProducer.ready := true.B` is still allowed. | ||
| `.asConsumer` is symmetric: it makes the flipped fields (e.g. `ready`) read-only while leaving aligned fields (e.g. `valid`) writable. | ||
|
|
||
| **Using a role on the wrong side.** A producer view on the left-hand side, or a consumer view on the right-hand side, is rejected regardless of which fields are touched. |
There was a problem hiding this comment.
again can you clarify if :>= would be allowed / flagged 'correctly' as an error?
There was a problem hiding this comment.
For the purposes of RHS as producer and LHS as consumer, the relationship is the same for :>= as it is for :<>=.
|
One example I was putting together that illustrates a bug in this current implementation: class MyBundle extends Bundle {
val inward = Flipped(Decoupled(UInt(8.W)))
val outward = Decoupled(UInt(8.W))
def wireAndSplit = {
val _w = Wire(new MyBundle)
this :<>= _w
(_w.outward.asConsumer, _w.inward.asProducer)
// The below should be isomorphic with the above but the below currently errors.
(_w.asConsumer.outward, _w.asConsumer.inward)
}
}
class Top extends Module {
val io = IO(new MyBundle)
val (out, in) = io.wireAndSplit
out :<= in
out :>= in
out :<>= in
}Put another way, just like how This PR needs some more work. |
Summary
The diff is large but it's mostly documentation and tests.
Release Notes
.asProducermarks the aligned fields of a bidirectional value as read-only (e.g.validandbits)..asConsumermarks the flipped fields of a bidirectional value as read-only (e.g.ready).Development notes