|
| 1 | +- Start Date: 2023-08-22 |
| 2 | +- RFC PR: [amaranth-lang/rfcs#18](https://github.com/amaranth-lang/rfcs/pull/18) |
| 3 | +- Amaranth Issue: [amaranth-lang/amaranth#873](https://github.com/amaranth-lang/amaranth/issues/873) |
| 4 | + |
| 5 | +# Reorganize vendor platforms |
| 6 | + |
| 7 | +## Summary |
| 8 | +[summary]: #summary |
| 9 | + |
| 10 | +Update `amaranth.vendor` namespace so that instead of: |
| 11 | + |
| 12 | +```python |
| 13 | +from amaranth.vendor.lattice_ecp5 import LatticeECP5Platform |
| 14 | +``` |
| 15 | + |
| 16 | +you would write: |
| 17 | + |
| 18 | +```python |
| 19 | +from amaranth.vendor import LatticeECP5Platform |
| 20 | +``` |
| 21 | + |
| 22 | + |
| 23 | +## Motivation |
| 24 | +[motivation]: #motivation |
| 25 | + |
| 26 | +Vendor names are ever-changing. Xilinx was bought by AMD and the brand has been phased out. Altera was bought by Intel and the brand has been phased out. SiliconBlue has been bought by Lattice (a long time ago) and the brand has *long* been phased out but still remains as "SB" in `SB_LUT` primitive name. |
| 27 | + |
| 28 | +In addition, we attempt to group FPGA families into a single file, like `vendor.lattice_machxo2_3l` that has been renamed from `vendor.lattice_machxo2`. This will likely include another FPGA family as soon as it becomes available. |
| 29 | + |
| 30 | +By tying module (and file) names to brand names we create churn. Every Amaranth release so far has included renaming of both platform class names and module names. This causes additional downstream breakage and annoys designers using Amaranth. |
| 31 | + |
| 32 | +## Guide-level explanation |
| 33 | +[guide-level-explanation]: #guide-level-explanation |
| 34 | + |
| 35 | +To target your FPGA-based project for a particular FPGA family, import the platform class corresponding to the FPGA family from `amaranth.vendor`, e.g.: |
| 36 | + |
| 37 | +```python |
| 38 | +from amaranth.vendor import LatticeECP5Platform |
| 39 | +``` |
| 40 | + |
| 41 | +## Reference-level explanation |
| 42 | +[reference-level-explanation]: #reference-level-explanation |
| 43 | + |
| 44 | +All of the `amaranth.vendor.name` modules are renamed to `amaranth.vendor._internal_name`. |
| 45 | + |
| 46 | +Python allows `__getattr__` to be present in modules: |
| 47 | + |
| 48 | + $ cat >x.py |
| 49 | + def __getattr__(self, name): |
| 50 | + return f"__getattr__({name!r})" |
| 51 | + $ python |
| 52 | + >>> from x import abc |
| 53 | + >>> abc |
| 54 | + "__getattr__('abc')" |
| 55 | + |
| 56 | +This allows us to make all the platform classes be present as-if they were defined in the `amaranth.vendor` modules, while retaining all of the benefits of having them in their own `amaranth.vendor._internal_name` module, such as lazy loading. |
| 57 | + |
| 58 | +## Drawbacks |
| 59 | +[drawbacks]: #drawbacks |
| 60 | + |
| 61 | +- Churn. |
| 62 | +- A somewhat unusual loading mechanism could cause confusion. |
| 63 | + |
| 64 | +## Rationale and alternatives |
| 65 | +[rationale-and-alternatives]: #rationale-and-alternatives |
| 66 | + |
| 67 | +Decoupling marketing/brand names from technical names is increasingly important as Amaranth evolves and supports more FPGA families. It allows us to maintain any internal hierarchy we want without it having any impact on downstream code, which solely operates on names imported from `amaranth.vendor`. |
| 68 | + |
| 69 | +## Prior art |
| 70 | +[prior-art]: #prior-art |
| 71 | + |
| 72 | +None. |
| 73 | + |
| 74 | +## Unresolved questions |
| 75 | +[unresolved-questions]: #unresolved-questions |
| 76 | + |
| 77 | +None. |
| 78 | + |
| 79 | +## Future possibilities |
| 80 | +[future-possibilities]: #future-possibilities |
| 81 | + |
| 82 | +None. |
0 commit comments