Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support for resetless clock domains
  • Loading branch information
enjoy-digital authored and Sebastien Bourdeauducq committed Apr 23, 2013
1 parent ceb0a99 commit f599fe4
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion examples/basic/local_cd.py
Expand Up @@ -6,7 +6,7 @@
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):
Expand Down
10 changes: 7 additions & 3 deletions migen/fhdl/structure.py
Expand Up @@ -246,19 +246,23 @@ def __getitem__(self, key):
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):
Expand Down
8 changes: 5 additions & 3 deletions migen/fhdl/tools.py
Expand Up @@ -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.
Expand Down
9 changes: 8 additions & 1 deletion migen/fhdl/verilog.py
Expand Up @@ -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"
Expand Down

0 comments on commit f599fe4

Please sign in to comment.