fhdl.dsl: comb/sync/sync.pix→d.comb/d.sync/d.pix.
authorwhitequark <cz@m-labs.hk>
Wed, 12 Dec 2018 12:38:24 +0000 (12:38 +0000)
committerwhitequark <cz@m-labs.hk>
Wed, 12 Dec 2018 12:38:24 +0000 (12:38 +0000)
examples/alu.py
examples/alu_hier.py
examples/arst.py
examples/clkdiv.py
examples/ctrl.py
examples/pmux.py
nmigen/back/rtlil.py
nmigen/fhdl/dsl.py
nmigen/genlib/cdc.py

index 1ffb176ef5048fa98a8cb20ca24a34efa401b1f5..456a75bacce68afc9c26f3766286f528bc4f48aa 100644 (file)
@@ -11,16 +11,16 @@ class ALU:
         self.co  = Signal()
 
     def get_fragment(self, platform):
-        f = Module()
-        with f.If(self.sel == 0b00):
-            f.comb += self.o.eq(self.a | self.b)
-        with f.Elif(self.sel == 0b01):
-            f.comb += self.o.eq(self.a & self.b)
-        with f.Elif(self.sel == 0b10):
-            f.comb += self.o.eq(self.a ^ self.b)
-        with f.Else():
-            f.comb += Cat(self.o, self.co).eq(self.a - self.b)
-        return f.lower(platform)
+        m = Module()
+        with m.If(self.sel == 0b00):
+            m.d.comb += self.o.eq(self.a | self.b)
+        with m.Elif(self.sel == 0b01):
+            m.d.comb += self.o.eq(self.a & self.b)
+        with m.Elif(self.sel == 0b10):
+            m.d.comb += self.o.eq(self.a ^ self.b)
+        with m.Else():
+            m.d.comb += Cat(self.o, self.co).eq(self.a - self.b)
+        return m.lower(platform)
 
 
 alu  = ALU(width=16)
index 52d2c19a343acb436bd607079b82c460f9723cd2..81640b2691f787536fa80a86292d4f6526eac0f8 100644 (file)
@@ -9,9 +9,9 @@ class Adder:
         self.o   = Signal(width)
 
     def get_fragment(self, platform):
-        f = Module()
-        f.comb += self.o.eq(self.a + self.b)
-        return f.lower(platform)
+        m = Module()
+        m.d.comb += self.o.eq(self.a + self.b)
+        return m.lower(platform)
 
 
 class Subtractor:
@@ -21,9 +21,9 @@ class Subtractor:
         self.o   = Signal(width)
 
     def get_fragment(self, platform):
-        f = Module()
-        f.comb += self.o.eq(self.a - self.b)
-        return f.lower(platform)
+        m = Module()
+        m.d.comb += self.o.eq(self.a - self.b)
+        return m.lower(platform)
 
 
 class ALU:
@@ -37,20 +37,20 @@ class ALU:
         self.sub = Subtractor(width)
 
     def get_fragment(self, platform):
-        f = Module()
-        f.submodules.add = self.add
-        f.submodules.sub = self.sub
-        f.comb += [
+        m = Module()
+        m.submodules.add = self.add
+        m.submodules.sub = self.sub
+        m.d.comb += [
             self.add.a.eq(self.a),
             self.sub.a.eq(self.a),
             self.add.b.eq(self.b),
             self.sub.b.eq(self.b),
         ]
-        with f.If(self.op):
-            f.comb += self.o.eq(self.sub.o)
-        with f.Else():
-            f.comb += self.o.eq(self.add.o)
-        return f.lower(platform)
+        with m.If(self.op):
+            m.d.comb += self.o.eq(self.sub.o)
+        with m.Else():
+            m.d.comb += self.o.eq(self.add.o)
+        return m.lower(platform)
 
 
 alu  = ALU(width=16)
index c8fa8c7d06d62630febde05bb684f0b166b7d710..d6fcd04da0ed46ee196de2da189f7c960f99d07c 100644 (file)
@@ -8,14 +8,14 @@ class ClockDivisor:
         self.o = Signal()
 
     def get_fragment(self, platform):
-        f = Module()
-        f.sync += self.v.eq(self.v + 1)
-        f.comb += self.o.eq(self.v[-1])
-        return f.lower(platform)
+        m = Module()
+        m.d.sync += self.v.eq(self.v + 1)
+        m.d.comb += self.o.eq(self.v[-1])
+        return m.lower(platform)
 
 
-sy = ClockDomain(async_reset=True)
+sync = ClockDomain(async_reset=True)
 ctr  = ClockDivisor(factor=16)
 frag = ctr.get_fragment(platform=None)
-# print(rtlil.convert(frag, ports=[sys.clk, sys.reset, ctr.o], clock_domains={"sys": sys}))
-print(verilog.convert(frag, ports=[sys.clk, sys.reset, ctr.o], clock_domains={"sys": sys}))
+# print(rtlil.convert(frag, ports=[sync.clk, sync.reset, ctr.o], clock_domains={"sync": sync}))
+print(verilog.convert(frag, ports=[sync.clk, sync.reset, ctr.o], clock_domains={"sync": sync}))
index f54505ee04431ec1d93426b0d846808383df729a..79eec933476d9c16fc6ece90b8094ef9d7c3d7c0 100644 (file)
@@ -8,14 +8,14 @@ class ClockDivisor:
         self.o = Signal()
 
     def get_fragment(self, platform):
-        f = Module()
-        f.sync += self.v.eq(self.v + 1)
-        f.comb += self.o.eq(self.v[-1])
-        return f.lower(platform)
+        m = Module()
+        m.d.sync += self.v.eq(self.v + 1)
+        m.d.comb += self.o.eq(self.v[-1])
+        return m.lower(platform)
 
 
-sy = ClockDomain()
+sync = ClockDomain()
 ctr  = ClockDivisor(factor=16)
 frag = ctr.get_fragment(platform=None)
-# print(rtlil.convert(frag, ports=[sys.clk, ctr.o], clock_domains={"sys": sys}))
-print(verilog.convert(frag, ports=[sys.clk, ctr.o], clock_domains={"sys": sys}))
+# print(rtlil.convert(frag, ports=[sync.clk, ctr.o], clock_domains={"sync": sync}))
+print(verilog.convert(frag, ports=[sync.clk, ctr.o], clock_domains={"sync": sync}))
index 9e6d76c7065fb71ff00f2f372d7770f20495eaf6..2d8fcf87121cdce35cf2b5acc2897a387b417cb2 100644 (file)
@@ -9,14 +9,14 @@ class ClockDivisor:
         self.ce = Signal()
 
     def get_fragment(self, platform):
-        f = Module()
-        f.sync += self.v.eq(self.v + 1)
-        f.comb += self.o.eq(self.v[-1])
-        return CEInserter(self.ce)(f.lower())
+        m = Module()
+        m.d.sync += self.v.eq(self.v + 1)
+        m.d.comb += self.o.eq(self.v[-1])
+        return CEInserter(self.ce)(m.lower(platform))
 
 
-sy = ClockDomain()
+sync = ClockDomain()
 ctr  = ClockDivisor(factor=16)
 frag = ctr.get_fragment(platform=None)
-# print(rtlil.convert(frag, ports=[sys.clk, ctr.o, ctr.ce], clock_domains={"sys": sys}))
-print(verilog.convert(frag, ports=[sys.clk, ctr.o, ctr.ce], clock_domains={"sys": sys}))
+# print(rtlil.convert(frag, ports=[sync.clk, ctr.o, ctr.ce], clock_domains={"sync": sync}))
+print(verilog.convert(frag, ports=[sync.clk, ctr.o, ctr.ce], clock_domains={"sync": sync}))
index be6c0d49f466766666925715ef67da288494ea67..e69068b4e209d956b5e2a3e81883d7f5810f8c2c 100644 (file)
@@ -11,16 +11,16 @@ class ParMux:
         self.o = Signal(width)
 
     def get_fragment(self, platform):
-        f = Module()
-        with f.Case(self.s, "--1"):
-            f.comb += self.o.eq(self.a)
-        with f.Case(self.s, "-1-"):
-            f.comb += self.o.eq(self.b)
-        with f.Case(self.s, "1--"):
-            f.comb += self.o.eq(self.c)
-        with f.Case(self.s):
-            f.comb += self.o.eq(0)
-        return f.lower(platform)
+        m = Module()
+        with m.Case(self.s, "--1"):
+            m.d.comb += self.o.eq(self.a)
+        with m.Case(self.s, "-1-"):
+            m.d.comb += self.o.eq(self.b)
+        with m.Case(self.s, "1--"):
+            m.d.comb += self.o.eq(self.c)
+        with m.Case(self.s):
+            m.d.comb += self.o.eq(0)
+        return m.lower(platform)
 
 
 pmux = ParMux(width=16)
index 2bc20a4300c0765c317aacc77f3d2c01fc45683e..eca42521edbdbab10ad73134f4fea0c85c1bc5e7 100644 (file)
@@ -449,11 +449,13 @@ def convert_fragment(builder, fragment, name, clock_domains):
                 triggers = []
                 if cd_name is None:
                     triggers.append(("always",))
-                else:
+                elif cd_name in clock_domains:
                     cd = clock_domains[cd_name]
                     triggers.append(("posedge", xformer(cd.clk)))
                     if cd.async_reset:
                         triggers.append(("posedge", xformer(cd.reset)))
+                else:
+                    raise ValueError("Clock domain {} not found in design".format(cd_name))
 
                 for trigger in triggers:
                     with process.sync(*trigger) as sync:
index 2b145416e3eff7917e4135db16dcd7c346674ae8..66759e84453377446dcc4be9042a62c2b06a91a2 100644 (file)
@@ -14,36 +14,30 @@ class _ModuleBuilderProxy:
         object.__setattr__(self, "_depth", depth)
 
 
-class _ModuleBuilderComb(_ModuleBuilderProxy):
-    def __iadd__(self, assigns):
-        self._builder._add_statement(assigns, cd=None, depth=self._depth)
-        return self
-
-
-class _ModuleBuilderSyncCD(_ModuleBuilderProxy):
-    def __init__(self, builder, depth, cd):
+class _ModuleBuilderDomain(_ModuleBuilderProxy):
+    def __init__(self, builder, depth, cd_name):
         super().__init__(builder, depth)
-        self._cd = cd
+        self._cd_name = cd_name
 
     def __iadd__(self, assigns):
-        self._builder._add_statement(assigns, cd=self._cd, depth=self._depth)
+        self._builder._add_statement(assigns, cd_name=self._cd_name, depth=self._depth)
         return self
 
 
-class _ModuleBuilderSync(_ModuleBuilderProxy):
-    def __iadd__(self, assigns):
-        self._builder._add_statement(assigns, cd="sys", depth=self._depth)
-        return self
-
+class _ModuleBuilderDomains(_ModuleBuilderProxy):
     def __getattr__(self, name):
-        return _ModuleBuilderSyncCD(self._builder, self._depth, name)
+        if name == "comb":
+            cd_name = None
+        else:
+            cd_name = name
+        return _ModuleBuilderDomain(self._builder, self._depth, cd_name)
 
     def __getitem__(self, name):
         return self.__getattr__(name)
 
     def __setattr__(self, name, value):
-        if not isinstance(value, _ModuleBuilderSyncCD):
-            raise AttributeError("Cannot assign sync.{} attribute - use += instead"
+        if not isinstance(value, _ModuleBuilderDomain):
+            raise AttributeError("Cannot assign d.{} attribute - use += instead"
                                  .format(name))
 
     def __setitem__(self, name, value):
@@ -53,15 +47,12 @@ class _ModuleBuilderSync(_ModuleBuilderProxy):
 class _ModuleBuilderRoot:
     def __init__(self, builder, depth):
         self._builder = builder
-        self.comb = _ModuleBuilderComb(builder, depth)
-        self.sync = _ModuleBuilderSync(builder, depth)
+        self.domain = self.d = _ModuleBuilderDomains(builder, depth)
 
-    def __setattr__(self, name, value):
-        if name == "comb" and not isinstance(value, _ModuleBuilderComb):
-            raise AttributeError("Cannot assign comb attribute - use += instead")
-        if name == "sync" and not isinstance(value, _ModuleBuilderSync):
-            raise AttributeError("Cannot assign sync attribute - use += instead")
-        super().__setattr__(name, value)
+    def __getattr__(self, name):
+        if name in ("comb", "sync"):
+            raise AttributeError("'{}' object has no attribute '{}'; did you mean 'd.{}'?"
+                                 .format(type(self).__name__, name, name))
 
 
 class _ModuleBuilderIf(_ModuleBuilderRoot):
@@ -201,12 +192,12 @@ class Module(_ModuleBuilderRoot):
         self._stmt_switch_test  = None
         self._stmt_switch_cases = OrderedDict()
 
-    def _add_statement(self, assigns, cd, depth):
-        def cd_name(cd):
-            if cd is None:
+    def _add_statement(self, assigns, cd_name, depth):
+        def cd_human_name(cd_name):
+            if cd_name is None:
                 return "comb"
             else:
-                return "sync.{}".format(cd)
+                return cd_name
 
         if depth < self._stmt_depth:
             self._flush()
@@ -218,12 +209,12 @@ class Module(_ModuleBuilderRoot):
 
             for signal in assign.lhs._lhs_signals():
                 if signal not in self._driving:
-                    self._driving[signal] = cd
-                elif self._driving[signal] != cd:
+                    self._driving[signal] = cd_name
+                elif self._driving[signal] != cd_name:
                     cd_curr = self._driving[signal]
-                    raise ValueError("Driver-driver conflict: trying to drive {!r} from {}, but "
-                                     "it is already driven from {}"
-                                     .format(signal, self.cd_name(cd), self.cd_name(cd_curr)))
+                    raise ValueError("Driver-driver conflict: trying to drive {!r} from d.{}, but "
+                                     "it is already driven from d.{}"
+                                     .format(signal, cd_human_name(cd), cd_human_name(cd_curr)))
 
             self._statements.append(assign)
 
index a6c1fc266381fbf3a715dbd13083621aea08f15e..1b5fffc9057e14ca04a9c25b5cc1a69103b6f2a2 100644 (file)
@@ -15,8 +15,11 @@ class MultiReg:
                       for i in range(n)]
 
     def get_fragment(self, platform):
-        f = Module()
+        if hasattr(platform, "get_multi_reg"):
+            return platform.get_multi_reg(self)
+
+        m = Module()
         for i, o in zip((self.i, *self._regs), self._regs):
-            f.sync[self.odomain] += o.eq(i)
-        f.comb += self.o.eq(self._regs[-1])
-        return f.lower(platform)
+            m.d[self.odomain] += o.eq(i)
+        m.d.comb += self.o.eq(self._regs[-1])
+        return m.lower(platform)