Skip to content

Commit 821154c

Browse files
committed
Add an RFC for InternalPort.
1 parent a838a3b commit 821154c

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

text/0078-internal-port.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
- Start Date: 2025-06-02
2+
- RFC PR: [amaranth-lang/rfcs#78](https://github.com/amaranth-lang/rfcs/pull/78)
3+
- Amaranth Issue: [amaranth-lang/amaranth#0000](https://github.com/amaranth-lang/amaranth/issues/0000)
4+
5+
# Internal I/O ports
6+
7+
## Summary
8+
[summary]: #summary
9+
10+
`SimulationPort` is renamed to `InternalPort`, and using it outside of simulation is allowed. It allows for connecting I/O port-expecting components to internal signals instead of external I/O ports.
11+
12+
## Motivation
13+
[motivation]: #motivation
14+
15+
[RFC 55](https://amaranth-lang.org/rfcs/0055-lib-io.html) has made way for a variety of reusable I/O components, capable of attaching to arbitrary `PortLike`s. However, their reusability is limitted by requiring external ports for all of their interface. This limitation comes up in two scenerios:
16+
17+
1. The component is used internally, to interface with other gateware within the same design.
18+
2. One of the optional pins of the I/O interface is unused and should be discarded (for outputs), or tied to a constant value (for inputs).
19+
20+
Having a way to connect such gateware to internal signals resolves both issues. Since we already have such capability in simulation, we only need to extend it to allow synthesis usage.
21+
22+
## Guide-level and reference-level explanation
23+
[guide-level-explanation]: #guide-level-explanation
24+
25+
`lib.io.SimulationPort` is renamed to `lib.io.InternalPort`. The old name is deprecated and will be removed in Amaranth 0.8.
26+
27+
Use of `InternalPort` is allowed with `lib.io.Buffer` and `lib.io.FFBuffer` regardless of the platform (and bypassing the platform hooks).
28+
29+
To simplify tying off unused input ports to constant values, `init=` keyword-only argument is added to the `InternalPort` constructor. Is is passed directly to the `init=` argument of the port's `i` signal. It is an error to use this argument with an output-only port.
30+
31+
## Drawbacks
32+
[drawbacks]: #drawbacks
33+
34+
- more complex I/O subsystem
35+
- the tie-off case could be better served by other means
36+
37+
## Rationale and alternatives
38+
[rationale-and-alternatives]: #rationale-and-alternatives
39+
40+
This is a fairly simple solution leveraging existing code. For the internal connection case, no other design is apparent. For tie-off, there are two other possibilities:
41+
42+
1. Have a separate `TieoffPort` class.
43+
44+
Such class could serve as a marker that the port output will always be discarded, or that input will always have the tieoff value, allowing for simplification in controller logic.
45+
46+
Further, fancy platform-specific buffer types (such as high data rate SERDES) could be trivially instantiated for tie-off ports (by simply doing nothing for discarded output, or replicating the tieoff value for input), which is not in general possible for arbitrary `InternalPort`.
47+
48+
2. Have an out-of-band mechanism that removes the unused port from the component's signature.
49+
50+
## Prior art
51+
[prior-art]: #prior-art
52+
53+
This RFC reuses existing `SimulationPort` machinery.
54+
55+
Passing around a triple of `(I, O, OE)` is a fairly standard way of connecting an I/O controller to other logic.
56+
57+
## Unresolved questions
58+
[unresolved-questions]: #unresolved-questions
59+
60+
- how should `DDRBuffer` interact with `InternalPort`, both in simulation and synthesis?
61+
62+
## Future possibilities
63+
[future-possibilities]: #future-possibilities
64+
65+
None.

0 commit comments

Comments
 (0)