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: 1c3079613b1f
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: a5fb9ba0737f
Choose a head ref
  • 2 commits
  • 3 files changed
  • 2 contributors

Commits on Dec 22, 2015

  1. sim: lower specials, closes #34

    jordens authored and sbourdeauducq committed Dec 22, 2015
    Copy the full SHA
    eb8e8d4 View commit details
  2. Copy the full SHA
    a5fb9ba View commit details
Showing with 51 additions and 46 deletions.
  1. +42 −1 migen/fhdl/tools.py
  2. +2 −44 migen/fhdl/verilog.py
  3. +7 −1 migen/sim/core.py
43 changes: 42 additions & 1 deletion migen/fhdl/tools.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from migen.fhdl.structure import *
from migen.fhdl.structure import _Slice, _Assign
from migen.fhdl.structure import _Slice, _Assign, _Fragment
from migen.fhdl.visit import NodeVisitor, NodeTransformer
from migen.fhdl.bitcontainer import value_bits_sign
from migen.util.misc import flat_iteration
@@ -296,3 +296,44 @@ def rename_clock_domain(f, old, new):
pass
else:
cd.rename(new)


def call_special_classmethod(overrides, obj, method, *args, **kwargs):
cl = obj.__class__
if cl in overrides:
cl = overrides[cl]
if hasattr(cl, method):
return getattr(cl, method)(obj, *args, **kwargs)
else:
return None


def _lower_specials_step(overrides, specials):
f = _Fragment()
lowered_specials = set()
for special in sorted(specials, key=lambda x: x.duid):
impl = call_special_classmethod(overrides, special, "lower")
if impl is not None:
f += impl.get_fragment()
lowered_specials.add(special)
return f, lowered_specials


def _can_lower(overrides, specials):
for special in specials:
cl = special.__class__
if cl in overrides:
cl = overrides[cl]
if hasattr(cl, "lower"):
return True
return False


def lower_specials(overrides, specials):
f, lowered_specials = _lower_specials_step(overrides, specials)
while _can_lower(overrides, f.specials):
f2, lowered_specials2 = _lower_specials_step(overrides, f.specials)
f += f2
lowered_specials |= lowered_specials2
f.specials -= lowered_specials2
return f, lowered_specials
46 changes: 2 additions & 44 deletions migen/fhdl/verilog.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
from migen.fhdl.tools import *
from migen.fhdl.bitcontainer import bits_for
from migen.fhdl.namer import build_namespace
from migen.fhdl.conv_output import ConvOutput

@@ -262,51 +261,10 @@ def _printsync(f, ns):
return r


def _call_special_classmethod(overrides, obj, method, *args, **kwargs):
cl = obj.__class__
if cl in overrides:
cl = overrides[cl]
if hasattr(cl, method):
return getattr(cl, method)(obj, *args, **kwargs)
else:
return None


def _lower_specials_step(overrides, specials):
f = _Fragment()
lowered_specials = set()
for special in sorted(specials, key=lambda x: x.duid):
impl = _call_special_classmethod(overrides, special, "lower")
if impl is not None:
f += impl.get_fragment()
lowered_specials.add(special)
return f, lowered_specials


def _can_lower(overrides, specials):
for special in specials:
cl = special.__class__
if cl in overrides:
cl = overrides[cl]
if hasattr(cl, "lower"):
return True
return False


def _lower_specials(overrides, specials):
f, lowered_specials = _lower_specials_step(overrides, specials)
while _can_lower(overrides, f.specials):
f2, lowered_specials2 = _lower_specials_step(overrides, f.specials)
f += f2
lowered_specials |= lowered_specials2
f.specials -= lowered_specials2
return f, lowered_specials


def _printspecials(overrides, specials, ns, add_data_file):
r = ""
for special in sorted(specials, key=lambda x: x.duid):
pr = _call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file)
pr = call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file)
if pr is None:
raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog")
r += pr
@@ -337,7 +295,7 @@ def convert(f, ios=None, name="top",
f = lower_complex_slices(f)
insert_resets(f)
f = lower_basics(f)
fs, lowered_specials = _lower_specials(special_overrides, f.specials)
fs, lowered_specials = lower_specials(special_overrides, f.specials)
f += lower_basics(fs)

ns = build_namespace(list_signals(f) \
8 changes: 7 additions & 1 deletion migen/sim/core.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
_Operator, _Slice, _ArrayProxy,
_Assign, _Fragment)
from migen.fhdl.bitcontainer import value_bits_sign
from migen.fhdl.tools import list_targets, insert_resets
from migen.fhdl.tools import list_targets, insert_resets, lower_specials
from migen.fhdl.simplify import MemoryToArray
from migen.fhdl.specials import _MemoryLocation
from migen.sim.vcd import VCDWriter, DummyVCDWriter
@@ -222,6 +222,12 @@ def __init__(self, fragment_or_module, generators, clocks={"sys": 10}, vcd_name=
self.fragment = fragment_or_module
else:
self.fragment = fragment_or_module.get_fragment()
fs, lowered = lower_specials(overrides={}, specials=self.fragment.specials)
self.fragment += fs
self.fragment.specials -= lowered
if self.fragment.specials:
raise ValueError("Could not lower all specials", self.fragment.specials)

if not isinstance(generators, dict):
generators = {"sys": generators}
self.generators = dict()