hdl.xfrm: handle mem.{Read,Write}Port in CEInserter.
authorwhitequark <cz@m-labs.hk>
Wed, 31 Jul 2019 05:19:24 +0000 (05:19 +0000)
committerwhitequark <cz@m-labs.hk>
Wed, 31 Jul 2019 05:20:05 +0000 (05:20 +0000)
Fixes #154.

nmigen/hdl/xfrm.py
nmigen/test/test_hdl_xfrm.py
nmigen/test/tools.py

index 334e1e41c665939675cc242553c63fd75f3f7c83..db3260ef5513955d94d761e90b13650988f09ffb 100644 (file)
@@ -570,6 +570,7 @@ class _ControlInserter(FragmentTransformer):
         self.src_loc = tracer.get_src_loc()
         return super().__call__(value)
 
+
 class ResetInserter(_ControlInserter):
     def _insert_control(self, fragment, domain, signals):
         stmts = [s.eq(Const(s.reset, s.nbits)) for s in signals if not s.reset_less]
@@ -580,3 +581,13 @@ class CEInserter(_ControlInserter):
     def _insert_control(self, fragment, domain, signals):
         stmts = [s.eq(s) for s in signals]
         fragment.add_statements(Switch(self.controls[domain], {0: stmts}, src_loc=self.src_loc))
+
+    def on_fragment(self, fragment):
+        new_fragment = super().on_fragment(fragment)
+        if isinstance(new_fragment, Instance) and new_fragment.type in ("$memrd", "$memwr"):
+            clk_port, clk_dir = new_fragment.named_ports["CLK"]
+            if isinstance(clk_port, ClockSignal) and clk_port.domain in self.controls:
+                en_port, en_dir = new_fragment.named_ports["EN"]
+                en_port = Mux(self.controls[clk_port.domain], en_port, Const(0, len(en_port)))
+                new_fragment.named_ports["EN"] = en_port, en_dir
+        return new_fragment
index fcf77c11009620c65b3de279b98300847f83fd96..24e4f548ab91e83e975a71baa7c7b05992295b11 100644 (file)
@@ -2,6 +2,7 @@ from ..hdl.ast import *
 from ..hdl.cd import *
 from ..hdl.ir import *
 from ..hdl.xfrm import *
+from ..hdl.mem import *
 from .tools import *
 
 
@@ -513,6 +514,20 @@ class CEInserterTestCase(FHDLTestCase):
         )
         """)
 
+    def test_ce_read_port(self):
+        mem = Memory(width=8, depth=4)
+        f = CEInserter(self.c1)(mem.read_port(transparent=False)).elaborate(platform=None)
+        self.assertRepr(f.named_ports["EN"][0], """
+        (m (sig c1) (sig mem_r_en) (const 1'd0))
+        """)
+
+    def test_ce_write_port(self):
+        mem = Memory(width=8, depth=4)
+        f = CEInserter(self.c1)(mem.write_port()).elaborate(platform=None)
+        self.assertRepr(f.named_ports["EN"][0], """
+        (m (sig c1) (cat (repl (slice (sig mem_w_en) 0:1) 8)) (const 8'd0))
+        """)
+
 
 class _MockElaboratable(Elaboratable):
     def __init__(self):
index 3d803ba1510f1d0495cc5028771629197b81accb..cb4ee4971abd6c9bdd89d24b2b90deda79e24f98 100644 (file)
@@ -18,7 +18,8 @@ __all__ = ["FHDLTestCase"]
 
 class FHDLTestCase(unittest.TestCase):
     def assertRepr(self, obj, repr_str):
-        obj = Statement.wrap(obj)
+        if isinstance(obj, list):
+            obj = Statement.wrap(obj)
         def prepare_repr(repr_str):
             repr_str = re.sub(r"\s+",   " ",  repr_str)
             repr_str = re.sub(r"\( (?=\()", "(", repr_str)