Support for resetless clock domains
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 23 Apr 2013 09:53:37 +0000 (11:53 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 23 Apr 2013 09:54:05 +0000 (11:54 +0200)
examples/basic/local_cd.py
migen/fhdl/structure.py
migen/fhdl/tools.py
migen/fhdl/verilog.py

index ca8200a18a0d2bdb4f47e2e3916c024b4a3f939f..bebd920edf99d81de91f7aa0aba2becc1bdef72e 100644 (file)
@@ -6,7 +6,7 @@ from migen.genlib.divider import Divider
 class CDM(Module):
        def __init__(self):
                self.submodules.divider = Divider(5)
-               self.clock_domains.cd_sys = ClockDomain()
+               self.clock_domains.cd_sys = ClockDomain(reset_less=True)
 
 class MultiMod(Module):
        def __init__(self):
index 355713c7601e17847f975bc0f53d1dcc8454429e..dea8dc7bf337e1074eb675ce4600c424e4d51090 100644 (file)
@@ -246,19 +246,23 @@ class Array(list):
                        return list.__getitem__(self, key)
 
 class ClockDomain:
-       def __init__(self, name=None):
+       def __init__(self, name=None, reset_less=False):
                self.name = tracer.get_obj_var_name(name)
                if self.name is None:
                        raise ValueError("Cannot extract clock domain name from code, need to specify.")
                if len(self.name) > 3 and self.name[:3] == "cd_":
                        self.name = self.name[3:]
                self.clk = Signal(name_override=self.name + "_clk")
-               self.rst = Signal(name_override=self.name + "_rst")
+               if reset_less:
+                       self.rst = None
+               else:
+                       self.rst = Signal(name_override=self.name + "_rst")
 
        def rename(self, new_name):
                self.name = new_name
                self.clk.name_override = new_name + "_clk"
-               self.rst.name_override = new_name + "_rst"
+               if self.rst is not None:
+                       self.rst.name_override = new_name + "_rst"
 
 class _ClockDomainList(list):
        def __getitem__(self, key):
index 7c556f8b92bc364a2e3596a2ca6b1162cdc8d6e4..333bfe472d5b4818ab4f31961154a8b24a5e31a3 100644 (file)
@@ -112,10 +112,12 @@ def is_variable(node):
        else:
                raise TypeError
 
-def insert_reset(rst, sl):
+def generate_reset(rst, sl):
        targets = list_targets(sl)
-       resetcode = [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.huid)]
-       return [If(rst, *resetcode).Else(*sl)]
+       return [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.huid)]
+
+def insert_reset(rst, sl):
+       return [If(rst, *generate_reset(rst, sl)).Else(*sl)]
 
 # Basics are FHDL structure elements that back-ends are not required to support
 # but can be expressed in terms of other elements (lowered) before conversion.
index a5ef01dd184911bfcea3cdef9789fe2755cab776..748db5b229a9e9c54e54ceb72124f06ac23ba67d 100644 (file)
@@ -203,12 +203,19 @@ def _printcomb(f, ns, display_run):
 def _insert_resets(f):
        newsync = dict()
        for k, v in f.sync.items():
-               newsync[k] = insert_reset(ResetSignal(k), v)
+               if f.clock_domains[k].rst is not None:
+                       newsync[k] = insert_reset(ResetSignal(k), v)
+               else:
+                       newsync[k] = v
        f.sync = newsync
 
 def _printsync(f, ns):
        r = ""
        for k, v in sorted(f.sync.items(), key=itemgetter(0)):
+               if f.clock_domains[k].rst is None:
+                       r += "initial begin\n"
+                       r += _printnode(ns, _AT_SIGNAL, 1, generate_reset(ResetSignal(k), v))
+                       r += "end\n\n"
                r += "always @(posedge " + ns.get_name(f.clock_domains[k].clk) + ") begin\n"
                r += _printnode(ns, _AT_SIGNAL, 1, v)
                r += "end\n\n"