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: cabae0c32b0c
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: fcd48dafec4e
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jul 25, 2013

  1. fhdl: introduce module decorators

    Sebastien Bourdeauducq committed Jul 25, 2013
    Copy the full SHA
    b367932 View commit details
  2. examples/two_dividers: demonstrate InsertCE and InsertReset decorators

    Sebastien Bourdeauducq committed Jul 25, 2013
    Copy the full SHA
    fcd48da View commit details
Showing with 88 additions and 5 deletions.
  1. +7 −5 examples/basic/two_dividers.py
  2. +80 −0 migen/fhdl/decorators.py
  3. +1 −0 migen/fhdl/std.py
12 changes: 7 additions & 5 deletions examples/basic/two_dividers.py
Original file line number Diff line number Diff line change
@@ -2,14 +2,16 @@
from migen.fhdl import verilog
from migen.genlib import divider

@DecorateModule(InsertReset)
@DecorateModule(InsertCE)
class Example(Module):
def __init__(self):
d1 = divider.Divider(16)
d2 = divider.Divider(16)
def __init__(self, width):
d1 = divider.Divider(width)
d2 = divider.Divider(width)
self.submodules += d1, d2
self.ios = {
d1.ready_o, d1.quotient_o, d1.remainder_o, d1.start_i, d1.dividend_i, d1.divisor_i,
d2.ready_o, d2.quotient_o, d2.remainder_o, d2.start_i, d2.dividend_i, d2.divisor_i}

example = Example()
print(verilog.convert(example, example.ios))
example = Example(16)
print(verilog.convert(example, example.ios | {example.ce, example.reset}))
80 changes: 80 additions & 0 deletions migen/fhdl/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from migen.fhdl.structure import *
from migen.fhdl.tools import insert_reset

class ModuleDecorator:
def __init__(self, decorated):
object.__setattr__(self, "_md_decorated", decorated)

def __getattr__(self, name):
return getattr(self._md_decorated, name)

def __setattr__(self, name, value):
return setattr(self._md_decorated, name, value)

# overload this in derived classes
def transform_fragment(self, f):
pass

def get_fragment(self):
f = self._md_decorated.get_fragment()
self.transform_fragment(f)
return f

class DecorateModule:
def __init__(self, decorator, *dec_args, **dec_kwargs):
self.decorator = decorator
self.dec_args = dec_args
self.dec_kwargs = dec_kwargs

def __call__(self, decorated):
def dfinit(dfself, *args, **kwargs):
self.decorator.__init__(dfself, decorated(*args, **kwargs),
*self.dec_args, **self.dec_kwargs)
typename = self.decorator.__name__ + "(" + decorated.__name__ + ")"
return type(typename, (self.decorator,), dict(__init__=dfinit))

class InsertControl(ModuleDecorator):
def __init__(self, control_name, decorated, clock_domains=None):
ModuleDecorator.__init__(self, decorated)

object.__setattr__(self, "_ic_control_name", control_name)
object.__setattr__(self, "_ic_clock_domains", clock_domains)

if clock_domains is None:
ctl = Signal(name=control_name)
assert(not hasattr(decorated, control_name))
object.__setattr__(self, control_name, ctl)
else:
for cd in clock_domains:
name = control_name + "_" + cd
ctl = Signal(name=name)
assert(not hasattr(decorated, name))
object.__setattr__(self, name, ctl)

def transform_fragment(self, f):
control_name = self._ic_control_name
clock_domains = self._ic_clock_domains
if clock_domains is None:
if len(f.sync) != 1:
raise ValueError("Control signal clock domains must be specified when module has more than one domain")
cdn = list(f.sync.keys())[0]
to_insert = [(getattr(self, control_name), cdn)]
else:
to_insert = [(getattr(self, control_name+"_"+cdn), cdn) for cdn in clock_domains]
self.transform_fragment_insert(f, to_insert)

class InsertCE(InsertControl):
def __init__(self, *args, **kwargs):
InsertControl.__init__(self, "ce", *args, **kwargs)

def transform_fragment_insert(self, f, to_insert):
for ce, cdn in to_insert:
f.sync[cdn] = [If(ce, *f.sync[cdn])]

class InsertReset(InsertControl):
def __init__(self, *args, **kwargs):
InsertControl.__init__(self, "reset", *args, **kwargs)

def transform_fragment_insert(self, f, to_insert):
for reset, cdn in to_insert:
f.sync[cdn] = insert_reset(reset, f.sync[cdn])
1 change: 1 addition & 0 deletions migen/fhdl/std.py
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@
from migen.fhdl.module import Module
from migen.fhdl.specials import TSTriple, Instance, Memory
from migen.fhdl.size import log2_int, bits_for, flen
from migen.fhdl.decorators import DecorateModule, InsertCE, InsertReset