Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: dc552893239d
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 17f2b176541e
Choose a head ref
  • 3 commits
  • 8 files changed
  • 1 contributor

Commits on Mar 18, 2013

  1. Lowering of Special expressions + support ClockSignal/ResetSignal

    Sebastien Bourdeauducq committed Mar 18, 2013
    Copy the full SHA
    7a06e94 View commit details
  2. examples/basic/arrays: demonstrate lowering of Array in Instance expr…

    …ession
    Sebastien Bourdeauducq committed Mar 18, 2013
    Copy the full SHA
    af4eb02 View commit details
  3. fhdl/verilog: optionally disable clock domain creation

    Sebastien Bourdeauducq committed Mar 18, 2013
    Copy the full SHA
    17f2b17 View commit details
Showing with 205 additions and 121 deletions.
  1. +7 −2 examples/basic/arrays.py
  2. +2 −2 migen/fhdl/module.py
  3. +54 −74 migen/fhdl/specials.py
  4. +12 −12 migen/fhdl/structure.py
  5. +88 −13 migen/fhdl/tools.py
  6. +13 −8 migen/fhdl/verilog.py
  7. +21 −1 migen/fhdl/visit.py
  8. +8 −9 migen/genlib/cdc.py
9 changes: 7 additions & 2 deletions examples/basic/arrays.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from migen.fhdl.structure import *
from migen.fhdl.specials import Instance
from migen.fhdl.module import Module
from migen.fhdl import verilog

class Example(Module):
def __init__(self):
dx = 5
dy = 5
dx = 2
dy = 2

x = Signal(max=dx)
y = Signal(max=dy)
@@ -20,4 +21,8 @@ def __init__(self):
my_2d_array[x][y].eq(inp)
)

ina = Array(Signal() for a in range(dx))
outa = Array(Signal() for a in range(dy))
self.specials += Instance("test", Instance.Output("O", outa[y]), Instance.Input("I", ina[x]))

print(verilog.convert(Example()))
4 changes: 2 additions & 2 deletions migen/fhdl/module.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

from migen.fhdl.structure import *
from migen.fhdl.specials import Special
from migen.fhdl.tools import flat_iteration
from migen.fhdl.tools import flat_iteration, rename_clock_domain

class FinalizeError(Exception):
pass
@@ -158,7 +158,7 @@ def finalize(self):
for mod_name, f in subfragments:
for cd in f.clock_domains:
if cd.name in needs_renaming:
f.rename_clock_domain(cd.name, mod_name + "_" + cd.name)
rename_clock_domain(f, cd.name, mod_name + "_" + cd.name)
# sum subfragments
for mod_name, f in subfragments:
self._fragment += f
128 changes: 54 additions & 74 deletions migen/fhdl/specials.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
from migen.fhdl.structure import *
from migen.fhdl.tools import list_signals, value_bits_sign
from migen.fhdl.tools import *
from migen.fhdl.tracer import get_obj_var_name
from migen.fhdl.verilog import _printexpr as verilog_printexpr

class Special(HUID):
def iter_expressions(self):
for x in []:
yield x

def rename_clock_domain(self, old, new):
pass
for obj, attr, direction in self.iter_expressions():
rename_clock_domain_expr(getattr(obj, attr), old, new)

def list_clock_domains(self):
r = set()
for obj, attr, direction in self.iter_expressions():
r |= list_clock_domains_expr(getattr(obj, attr))
return r

def get_clock_domains(self):
return set()
def list_ios(self, ins, outs, inouts):
r = set()
for obj, attr, direction in self.iter_expressions():
if (direction == SPECIAL_INPUT and ins) \
or (direction == SPECIAL_OUTPUT and outs) \
or (direction == SPECIAL_INOUT and inouts):
signals = list_signals(getattr(obj, attr))
r.update(signals)
return r

class Tristate(Special):
def __init__(self, target, o, oe, i=None):
@@ -18,16 +36,13 @@ def __init__(self, target, o, oe, i=None):
self.oe = oe
self.i = i

def list_ios(self, ins, outs, inouts):
r = set()
if inouts:
r.update(list_signals(self.target))
if ins:
r.update(list_signals(self.o))
r.update(list_signals(self.oe))
if outs:
r.update(list_signals(self.i))
return r
def iter_expressions(self):
for attr, target_context in [
("target", SPECIAL_INOUT),
("o", SPECIAL_INPUT),
("oe", SPECIAL_INPUT),
("i", SPECIAL_OUTPUT)]:
yield self, attr, target_context

@staticmethod
def emit_verilog(tristate, ns, clock_domains):
@@ -79,40 +94,19 @@ def __init__(self, name, value):
self.name = name
self.value = value

class _CR:
def __init__(self, name_inst, domain="sys", invert=False):
self.name_inst = name_inst
self.domain = domain
self.invert = invert
class ClockPort(_CR):
pass
class ResetPort(_CR):
pass

def get_io(self, name):
for item in self.items:
if isinstance(item, Instance._IO) and item.name == name:
return item.expr

def rename_clock_domain(self, old, new):
for cr in filter(lambda x: isinstance(x, Instance._CR), self.items):
if cr.domain == old:
cr.domain = new

def get_clock_domains(self):
return set(cr.domain
for cr in filter(lambda x: isinstance(x, Instance._CR), self.items))

def list_ios(self, ins, outs, inouts):
subsets = [list_signals(item.expr) for item in filter(lambda x:
(ins and isinstance(x, Instance.Input))
or (outs and isinstance(x, Instance.Output))
or (inouts and isinstance(x, Instance.InOut)),
self.items)]
if subsets:
return set.union(*subsets)
else:
return set()
def iter_expressions(self):
for item in self.items:
if isinstance(item, Instance.Input):
yield item, "expr", SPECIAL_INPUT
elif isinstance(item, Instance.Output):
yield item, "expr", SPECIAL_OUTPUT
elif isinstance(item, Instance.InOut):
yield item, "expr", SPECIAL_INOUT

@staticmethod
def emit_verilog(instance, ns, clock_domains):
@@ -144,20 +138,10 @@ def emit_verilog(instance, ns, clock_domains):
if isinstance(p, Instance._IO):
name_inst = p.name
name_design = verilog_printexpr(ns, p.expr)[0]
elif isinstance(p, Instance.ClockPort):
name_inst = p.name_inst
name_design = ns.get_name(clock_domains[p.domain].clk)
if p.invert:
name_design = "~" + name_design
elif isinstance(p, Instance.ResetPort):
name_inst = p.name_inst
name_design = ns.get_name(clock_domains[p.domain].rst)
else:
continue
if not firstp:
r += ",\n"
firstp = False
r += "\t." + name_inst + "(" + name_design + ")"
if not firstp:
r += ",\n"
firstp = False
r += "\t." + name_inst + "(" + name_design + ")"
if not firstp:
r += "\n"
r += ");\n\n"
@@ -214,27 +198,26 @@ def get_port(self, write_capable=False, async_read=False,
self.ports.append(mp)
return mp

def iter_expressions(self):
for p in self.ports:
for attr, target_context in [
("adr", SPECIAL_INPUT),
("we", SPECIAL_INPUT),
("dat_w", SPECIAL_INPUT),
("re", SPECIAL_INPUT),
("dat_r", SPECIAL_OUTPUT)]:
yield p, attr, target_context

def rename_clock_domain(self, old, new):
# port expressions are always signals - no need to call Special.rename_clock_domain
for port in self.ports:
if port.clock_domain == old:
port.clock_domain = new

def get_clock_domains(self):
def list_clock_domains(self):
# port expressions are always signals - no need to call Special.list_clock_domains
return set(port.clock_domain for port in self.ports)

def list_ios(self, ins, outs, inouts):
s = set()
def add(*sigs):
for sig in sigs:
if sig is not None:
s.add(sig)
for p in self.ports:
if ins:
add(p.adr, p.we, p.dat_w, p.re)
if outs:
add(p.dat_r)
return s

@staticmethod
def emit_verilog(memory, ns, clock_domains):
r = ""
@@ -315,9 +298,6 @@ def __init__(self, template, **signals):
self.template = template
self.signals = signals

def list_ios(self, ins, outs, inouts):
return set()

@staticmethod
def emit_verilog(directive, ns, clock_domains):
name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
24 changes: 12 additions & 12 deletions migen/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -170,6 +170,16 @@ def __len__(self): # TODO: remove (use tools.value_bits_sign instead)
def __repr__(self):
return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"

class ClockSignal(Value):
def __init__(self, cd="sys"):
Value.__init__(self)
self.cd = cd

class ResetSignal(Value):
def __init__(self, cd="sys"):
Value.__init__(self)
self.cd = cd

# statements

class _Assign:
@@ -260,6 +270,8 @@ def __getitem__(self, key):
else:
return list.__getitem__(self, key)

(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)

class Fragment:
def __init__(self, comb=None, sync=None, specials=None, clock_domains=None, sim=None):
if comb is None: comb = []
@@ -287,15 +299,3 @@ def __add__(self, other):
self.specials | other.specials,
self.clock_domains + other.clock_domains,
self.sim + other.sim)

def rename_clock_domain(self, old, new):
self.sync[new] = self.sync[old]
del self.sync[old]
for special in self.specials:
special.rename_clock_domain(old, new)
try:
cd = self.clock_domains[old]
except KeyError:
pass
else:
cd.rename(new)
Loading