Repository: amaranth-lang/amaranth
Pull request #1247 (2024-03-26 18:20:54)

hdl._ir: rename `Instance.named_ports` to `Instance.ports`.
Made possible by the new port propagation code freeing up the name.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1247?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) Report
Attention: Patch coverage is `93.75000%` with `1 lines` in your changes are missing coverage. Please review.
> Project coverage is 89.84%. Comparing base [(`fa2adbe`)](https://app.codecov.io/gh/amaranth-lang/amaranth/commit/fa2adbef84ca173d3c19fba37cfd7a3a042635f5?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) to head [(`875be4a`)](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1247?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang).

| [Files](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1247?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) | Patch % | Lines |
|---|---|---|
| [amaranth/hdl/\_xfrm.py](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1247?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang#diff-YW1hcmFudGgvaGRsL194ZnJtLnB5) | 85.71% | [1 Missing :warning: ](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1247?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1247      +/-   ##
==========================================
- Coverage   89.87%   89.84%   -0.04%     
==========================================
  Files          43       43              
  Lines        9992     9992              
  Branches     2417     2417              
==========================================
- Hits         8980     8977       -3     
- Misses        818      819       +1     
- Partials      194      196       +2     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/amaranth-lang/amaranth/pull/1247?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=amaranth-lang).


Patch:
diff --git a/amaranth/hdl/_ir.py b/amaranth/hdl/_ir.py
index f3e9fc9..9190dfd 100644
--- a/amaranth/hdl/_ir.py
+++ b/amaranth/hdl/_ir.py
@@ -309,9 +309,9 @@ class Instance(Fragment):
     def __init__(self, type, *args, src_loc=None, src_loc_at=0, **kwargs):
         super().__init__(src_loc=src_loc or tracer.get_src_loc(src_loc_at))
 
-        self.type        = type
-        self.parameters  = OrderedDict()
-        self.named_ports = OrderedDict()
+        self.type       = type
+        self.parameters = OrderedDict()
+        self.ports      = OrderedDict()
 
         for (kind, name, value) in args:
             if kind == "a":
@@ -324,7 +324,7 @@ class Instance(Fragment):
                 else:
                     if not isinstance(value, _ast.IOValue):
                         value = _ast.Value.cast(value)
-                self.named_ports[name] = (value, kind)
+                self.ports[name] = (value, kind)
             else:
                 raise NameError("Instance argument {!r} should be a tuple (kind, name, value) "
                                 "where kind is one of \"a\", \"p\", \"i\", \"o\", or \"io\""
@@ -338,13 +338,13 @@ class Instance(Fragment):
             elif kw.startswith("i_"):
                 if not isinstance(arg, _ast.IOValue):
                     arg = _ast.Value.cast(arg)
-                self.named_ports[kw[2:]] = (arg, "i")
+                self.ports[kw[2:]] = (arg, "i")
             elif kw.startswith("o_"):
                 if not isinstance(arg, _ast.IOValue):
                     arg = _ast.Value.cast(arg)
-                self.named_ports[kw[2:]] = (arg, "o")
+                self.ports[kw[2:]] = (arg, "o")
             elif kw.startswith("io_"):
-                self.named_ports[kw[3:]] = (_ast.IOValue.cast(arg), "io")
+                self.ports[kw[3:]] = (_ast.IOValue.cast(arg), "io")
             else:
                 raise NameError("Instance keyword argument {}={!r} does not start with one of "
                                 "\"a_\", \"p_\", \"i_\", \"o_\", or \"io_\""
@@ -481,7 +481,7 @@ class Design:
         """Collects used signals and IO ports for a fragment and all its subfragments."""
         from . import _mem
         if isinstance(fragment, _ir.Instance):
-            for conn, kind in fragment.named_ports.values():
+            for conn, kind in fragment.ports.values():
                 if isinstance(conn, _ast.IOValue):
                     for port in conn._ioports():
                         self._use_io_port(fragment, port)
@@ -1194,7 +1194,7 @@ class NetlistEmitter:
         ports_io = {}
         outputs = []
         next_output_bit = 0
-        for port_name, (port_conn, dir) in instance.named_ports.items():
+        for port_name, (port_conn, dir) in instance.ports.items():
             if isinstance(port_conn, _ast.IOValue):
                 if dir == 'i':
                     xlat_dir = _nir.IODirection.Input
diff --git a/amaranth/hdl/_xfrm.py b/amaranth/hdl/_xfrm.py
index 85ff344..cd0200e 100644
--- a/amaranth/hdl/_xfrm.py
+++ b/amaranth/hdl/_xfrm.py
@@ -232,15 +232,15 @@ class FragmentTransformer:
         for subfragment, name, src_loc in fragment.subfragments:
             new_fragment.add_subfragment(self(subfragment), name, src_loc=src_loc)
 
-    def map_named_ports(self, fragment, new_fragment):
+    def map_ports(self, fragment, new_fragment):
         if hasattr(self, "on_value"):
-            for name, (value, dir) in fragment.named_ports.items():
+            for name, (value, dir) in fragment.ports.items():
                 if isinstance(value, Value):
-                    new_fragment.named_ports[name] = self.on_value(value), dir
+                    new_fragment.ports[name] = self.on_value(value), dir
                 else:
-                    new_fragment.named_ports[name] = value, dir
+                    new_fragment.ports[name] = value, dir
         else:
-            new_fragment.named_ports = OrderedDict(fragment.named_ports.items())
+            new_fragment.ports = OrderedDict(fragment.ports.items())
 
     def map_domains(self, fragment, new_fragment):
         for domain in fragment.iter_domains():
@@ -302,7 +302,7 @@ class FragmentTransformer:
         elif isinstance(fragment, Instance):
             new_fragment = Instance(fragment.type, src_loc=fragment.src_loc)
             new_fragment.parameters = OrderedDict(fragment.parameters)
-            self.map_named_ports(fragment, new_fragment)
+            self.map_ports(fragment, new_fragment)
         elif isinstance(fragment, IOBufferInstance):
             if hasattr(self, "on_value"):
                 new_fragment = IOBufferInstance(
@@ -452,7 +452,7 @@ class DomainCollector(ValueVisitor, StatementVisitor):
                 self._add_used_domain(port._domain)
 
         if isinstance(fragment, Instance):
-            for name, (value, dir) in fragment.named_ports.items():
+            for name, (value, dir) in fragment.ports.items():
                 if not isinstance(value, IOValue):
                     self.on_value(value)
 


Test patch:
diff --git a/tests/test_hdl_ir.py b/tests/test_hdl_ir.py
index 133c32f..a1de10b 100644
--- a/tests/test_hdl_ir.py
+++ b/tests/test_hdl_ir.py
@@ -721,7 +721,7 @@ class InstanceTestCase(FHDLTestCase):
             ("PARAM1", 0x1234),
             ("PARAM2", 0x5678),
         ]))
-        self.assertEqual(inst.named_ports, OrderedDict([
+        self.assertEqual(inst.ports, OrderedDict([
             ("s1", (s1, "i")),
             ("s2", (s2, "o")),
             ("io1", (io1, "i")),
@@ -741,10 +741,10 @@ class InstanceTestCase(FHDLTestCase):
             i_s3=3,
             io_s4=Cat(),
         )
-        self.assertRepr(inst.named_ports["s1"][0], "(const 1'd1)")
-        self.assertRepr(inst.named_ports["s2"][0], "(io-cat )")
-        self.assertRepr(inst.named_ports["s3"][0], "(const 2'd3)")
-        self.assertRepr(inst.named_ports["s4"][0], "(io-cat )")
+        self.assertRepr(inst.ports["s1"][0], "(const 1'd1)")
+        self.assertRepr(inst.ports["s2"][0], "(io-cat )")
+        self.assertRepr(inst.ports["s3"][0], "(const 2'd3)")
+        self.assertRepr(inst.ports["s4"][0], "(io-cat )")
 
     def test_wrong_construct_arg(self):
         s = Signal()
@@ -782,7 +782,7 @@ class InstanceTestCase(FHDLTestCase):
         f = self.inst
         self.assertEqual(f.type, "cpu")
         self.assertEqual(f.parameters, OrderedDict([("RESET", 0x1234)]))
-        self.assertEqual(list(f.named_ports.keys()), ["clk", "rst", "stb", "data", "pins"])
+        self.assertEqual(list(f.ports.keys()), ["clk", "rst", "stb", "data", "pins"])
 
     def test_prepare_attrs(self):
         self.setUp_cpu()