amaranth icon indicating copy to clipboard operation
amaranth copied to clipboard

A "must use" flag that can be put on signals that should not be left unconnected

Open whitequark opened this issue 1 year ago • 1 comments

This would be mainly stream's ready and valid signals, since if those are present, it is exceptionally rare that they should be left hanging, and this can cause hard to find issues in designs that heavily use streams.

Prior art would be #[must_use] in Rust, and [[nodiscard]] in C++17.

whitequark avatar Aug 28 '24 22:08 whitequark

I've discussed this with @wanda-phi. Design for this feature is trickier than it looks because components may internally use patterns like:

with m.If(self.o_stream.valid & self.o_stream.ready):
    ...

and these patterns should not be considered a "use" of the output signal.

This means that the feature would have to consist of:

  1. A way to determine and remember the "owning elaboratable" of a port member.
  2. A way to specify that a port member must be used.
  3. A way to find out whether it is indeed used, and emit a diagnostic if it's not.

The first two will necessarily be a part of the surface language, directly or indirectly.

Right now signals are not associated with elaboratables at all. I propose making it the responsibility of amaranth.lib.wiring.Component to do so, since this avoids either having to specify it manually like Signal(owner=self) (which is burdensome when the signal is nested deeply in the interface), or having to inspect the frame of the caller (which is brittle and difficult to teach).

To specify that a port member must be used, I propose extending the syntax to use In(..., must_use=True) or Out(..., must_use=True). I'll leave whether the syntax should do anything for interface members to the RFC.

Since our policy currently states that lib.wiring cannot use private APIs, there will also need to be some additional API to tie the signal to the component and specify that it must be used. I'll leave the design of that API to the RFC.

To find out whether the signal of a port member is used, NIR can be traversed. The details of this can be left to the RFC.

whitequark avatar Sep 05 '24 18:09 whitequark