From: whitequark Date: Wed, 31 Jul 2019 05:19:24 +0000 (+0000) Subject: hdl.xfrm: handle mem.{Read,Write}Port in CEInserter. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2455a7af0deb29440bff3c15b1cebc654970d3ac;p=nmigen.git hdl.xfrm: handle mem.{Read,Write}Port in CEInserter. Fixes #154. --- diff --git a/nmigen/hdl/xfrm.py b/nmigen/hdl/xfrm.py index 334e1e4..db3260e 100644 --- a/nmigen/hdl/xfrm.py +++ b/nmigen/hdl/xfrm.py @@ -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 diff --git a/nmigen/test/test_hdl_xfrm.py b/nmigen/test/test_hdl_xfrm.py index fcf77c1..24e4f54 100644 --- a/nmigen/test/test_hdl_xfrm.py +++ b/nmigen/test/test_hdl_xfrm.py @@ -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): diff --git a/nmigen/test/tools.py b/nmigen/test/tools.py index 3d803ba..cb4ee49 100644 --- a/nmigen/test/tools.py +++ b/nmigen/test/tools.py @@ -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)