Skip to content

Add an RFC for InternalPort. #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions text/0078-internal-port.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
- Start Date: 2025-06-02
- RFC PR: [amaranth-lang/rfcs#78](https://github.com/amaranth-lang/rfcs/pull/78)
- Amaranth Issue: [amaranth-lang/amaranth#0000](https://github.com/amaranth-lang/amaranth/issues/0000)

# Internal I/O ports

## Summary
[summary]: #summary

`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.

## Motivation
[motivation]: #motivation

[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:

1. The component is used internally, to interface with other gateware within the same design.
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).

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.

## Guide-level and reference-level explanation
[guide-level-explanation]: #guide-level-explanation

`lib.io.SimulationPort` is renamed to `lib.io.InternalPort`. The old name is deprecated and will be removed in Amaranth 0.7.

Use of `InternalPort` is allowed with `lib.io.Buffer` and `lib.io.FFBuffer` regardless of the platform (and bypassing the platform hooks).

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.

## Drawbacks
[drawbacks]: #drawbacks

- more complex I/O subsystem
- the tie-off case could be better served by other means

## Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

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:

1. Have a separate `TieoffPort` class.

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.

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`.

2. Have an out-of-band mechanism that removes the unused port from the component's signature.

## Prior art
[prior-art]: #prior-art

This RFC reuses existing `SimulationPort` machinery.

Passing around a triple of `(I, O, OE)` is a fairly standard way of connecting an I/O controller to other logic.

## Unresolved questions
[unresolved-questions]: #unresolved-questions

- how should `DDRBuffer` interact with `InternalPort`, both in simulation and synthesis?

## Future possibilities
[future-possibilities]: #future-possibilities

None.