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/nmigen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ad9b45adcd44
Choose a base ref
...
head repository: m-labs/nmigen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 181952dbf867
Choose a head ref
  • 3 commits
  • 8 files changed
  • 1 contributor

Commits on Dec 12, 2018

  1. fhdl.ast.Signal: implement .like().

    whitequark committed Dec 12, 2018
    Copy the full SHA
    1d4d00a View commit details
  2. compat.fhdl.bitcontainer: import/wrap Migen code.

    whitequark committed Dec 12, 2018
    Copy the full SHA
    356852a View commit details
  3. Copy the full SHA
    181952d View commit details
11 changes: 11 additions & 0 deletions nmigen/compat/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .fhdl.structure import *
from .fhdl.module import *
# from .fhdl.specials import *
from .fhdl.bitcontainer import *
# from .fhdl.decorators import *
# from .fhdl.simplify import *

# from .sim import *

# from .genlib.record import *
# from .genlib.fsm import *
Empty file added nmigen/compat/fhdl/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions nmigen/compat/fhdl/bitcontainer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from ... import tools
from ...fhdl import ast
from ...tools import deprecated


__all__ = ["log2_int", "bits_for", "value_bits_sign"]


@deprecated("instead of `log2_int`, use `nmigen.tools.log2_int`")
def log2_int(n, need_pow2=True):
return tools.log2_int(n, need_pow2)


@deprecated("instead of `bits_for`, use `nmigen.tools.bits_for`")
def bits_for(n, require_sign_bit=False):
return tools.bits_for(n, require_sign_bit)


@deprecated("instead of `value_bits_sign(v)`, use `v.bits_sign()`")
def value_bits_sign(v):
return ast.Value.wrap(v).bits_sign()
132 changes: 132 additions & 0 deletions nmigen/compat/fhdl/module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
from collections import Iterable

from ...tools import flatten, deprecated
from ...fhdl import dsl


__all__ = ["Module", "FinalizeError"]


def _flat_list(e):
if isinstance(e, Iterable):
return list(flatten(e))
else:
return [e]


class CompatFinalizeError(Exception):
pass


FinalizeError = CompatFinalizeError


class _CompatModuleProxy:
def __init__(self, cm):
object.__setattr__(self, "_cm", cm)


class _CompatModuleComb(_CompatModuleProxy):
@deprecated("instead of `self.comb +=`, use `m.d.comb +=`")
def __iadd__(self, assigns):
self._cm._module._add_statement(assigns, cd_name=None, depth=0, compat_mode=True)
return self


class _CompatModuleSyncCD:
def __init__(self, cm, cd):
self._cm = cm
self._cd = cd

@deprecated("instead of `self.sync.<domain> +=`, use `m.d.<domain> +=`")
def __iadd__(self, assigns):
self._cm._module._add_statement(assigns, cd_name=self._cd, depth=0, compat_mode=True)
return self


class _CompatModuleSync(_CompatModuleProxy):
@deprecated("instead of `self.sync +=`, use `m.d.sync +=`")
def __iadd__(self, assigns):
self._cm._module._add_statement(assigns, cd_name="sync", depth=0, compat_mode=True)
return self

def __getattr__(self, name):
return _CompatModuleSyncCD(self._cm, name)

def __setattr__(self, name, value):
if not isinstance(value, _ModuleSyncCD):
raise AttributeError("Attempted to assign sync property - use += instead")


class _CompatModuleForwardAttr:
@deprecated("TODO")
def __setattr__(self, name, value):
self.__iadd__(value)
setattr(self._cm, name, value)


class _CompatModuleSpecials(_CompatModuleProxy, _CompatModuleForwardAttr):
@deprecated("TODO")
def __iadd__(self, other):
self._cm._fragment.specials |= set(_flat_list(other))
return self


class _CompatModuleSubmodules(_CompatModuleProxy):
@deprecated("TODO")
def __setattr__(self, name, value):
self._cm._submodules += [(name, e) for e in _flat_list(value)]
setattr(self._cm, name, value)

@deprecated("TODO")
def __iadd__(self, other):
self._cm._submodules += [(None, e) for e in _flat_list(other)]
return self


class _CompatModuleClockDomains(_CompatModuleProxy, _CompatModuleForwardAttr):
@deprecated("TODO")
def __iadd__(self, other):
self._cm._fragment.clock_domains += _flat_list(other)
return self


class CompatModule:
def get_fragment(self):
assert not self.get_fragment_called
self.get_fragment_called = True
self.finalize()
return self._fragment

def __getattr__(self, name):
if name == "comb":
return _CompatModuleComb(self)
elif name == "sync":
return _CompatModuleSync(self)
elif name == "specials":
return _CompatModuleSpecials(self)
elif name == "submodules":
return _CompatModuleSubmodules(self)
elif name == "clock_domains":
return _CompatModuleClockDomains(self)
elif name == "finalized":
self.finalized = False
return self.finalized
elif name == "_module":
self._module = dsl.Module()
return self._module
elif name == "_submodules":
self._submodules = []
return self._submodules
elif name == "_clock_domains":
self._clock_domains = []
return self._clock_domains
elif name == "get_fragment_called":
self.get_fragment_called = False
return self.get_fragment_called
else:
raise AttributeError("'{}' object has no attribute '{}'"
.format(type(self).__name__, name))


Module = CompatModule
65 changes: 65 additions & 0 deletions nmigen/compat/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from collections import OrderedDict

from ...tools import deprecated
from ...fhdl import ast
from ...fhdl.ast import DUID, Value, Signal, Mux, Cat, Repl, Const, C, ClockSignal, ResetSignal
from ...fhdl.cd import ClockDomain


__all__ = ["DUID", "wrap", "Mux", "Cat", "Replicate", "Constant", "C", "Signal", "ClockSignal",
"ResetSignal", "If", "Case", "Array", "ClockDomain",
"SPECIAL_INPUT", "SPECIAL_OUTPUT", "SPECIAL_INOUT"]


@deprecated("instead of `wrap`, use `Value.wrap`")
def wrap(v):
return Value.wrap(v)


@deprecated("instead of `Replicate`, use `Repl`")
def Replicate(v, n):
return Repl(v, n)


@deprecated("instead of `Constant`, use `Const`")
def Constant(value, bits_sign=None):
return Const(value, bits_sign)


class If(ast.Switch):
@deprecated("instead of `If(cond, ...)`, use `with m.If(cond): ...`")
def __init__(self, cond, *stmts):
super().__init__(cond, {"1": ast.Statement.wrap(stmts)})

@deprecated("instead of `.Elif(cond, ...)`, use `with m.Elif(cond): ...`")
def Elif(self, cond, *stmts):
self.cases = OrderedDict(("-" + k, v) for k, v in self.cases.items())
self.cases["1" + "-" * len(self.test)] = ast.Statement.wrap(stmts)
self.test = Cat(self.test, cond)
return self

@deprecated("instead of `.Else(...)`, use `with m.Else(): ...`")
def Else(self, *stmts):
self.cases["-" * len(self.test)] = ast.Statement.wrap(stmts)
return self


class Case(ast.Switch):
@deprecated("instead of `migen.fhdl.structure.Case`, use `with m.Case():`")
def __init__(self, test, cases):
new_cases = []
for k, v in cases.items():
if k == "default":
k = "-" * len(ast.Value.wrap(test))
new_cases.append((k, v))
super().__init__(test, OrderedDict(new_cases))

def makedefault(self, key=None):
raise NotImplementedError


def Array(*args):
raise NotImplementedError


(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)
15 changes: 15 additions & 0 deletions nmigen/fhdl/ast.py
Original file line number Diff line number Diff line change
@@ -553,6 +553,21 @@ def __init__(self, bits_sign=None, name=None, reset=0, reset_less=False, min=Non

self.attrs = OrderedDict(() if attrs is None else attrs)

@classmethod
def like(cls, other, **kwargs):
"""Create Signal based on another.
Parameters
----------
other : Value
Object to base this Signal on.
"""
kw = dict(bits_sign=cls.wrap(other).bits_sign())
if isinstance(other, cls):
kw.update(reset=other.reset.value, reset_less=other.reset_less, attrs=other.attrs)
kw.update(kwargs)
return cls(**kw)

def bits_sign(self):
return self.nbits, self.signed

12 changes: 7 additions & 5 deletions nmigen/fhdl/dsl.py
Original file line number Diff line number Diff line change
@@ -192,7 +192,7 @@ def _flush(self):
self._stmt_switch_test = None
self._stmt_switch_cases = OrderedDict()

def _add_statement(self, assigns, cd_name, depth):
def _add_statement(self, assigns, cd_name, depth, compat_mode=False):
def cd_human_name(cd_name):
if cd_name is None:
return "comb"
@@ -204,17 +204,19 @@ def cd_human_name(cd_name):
self._stmt_depth = depth

for assign in Statement.wrap(assigns):
if not isinstance(assign, Assign):
raise TypeError("Only assignments can be appended to {}".format(self.cd_name(cd)))
if not compat_mode and not isinstance(assign, Assign):
raise TypeError("Only assignments can be appended to {}"
.format(cd_human_name(cd_name)))

for signal in assign.lhs._lhs_signals():
for signal in assign._lhs_signals():
if signal not in self._driving:
self._driving[signal] = cd_name
elif self._driving[signal] != cd_name:
cd_curr = self._driving[signal]
raise ValueError("Driver-driver conflict: trying to drive {!r} from d.{}, but "
"it is already driven from d.{}"
.format(signal, cd_human_name(cd), cd_human_name(cd_curr)))
.format(signal, cd_human_name(cd_name),
cd_human_name(cd_curr)))

self._statements.append(assign)

14 changes: 13 additions & 1 deletion nmigen/tools.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from collections import Iterable
import functools
import warnings


__all__ = ["flatten", "union", "log2_int", "bits_for"]
__all__ = ["flatten", "union", "log2_int", "bits_for", "deprecated"]


def flatten(i):
@@ -40,3 +42,13 @@ def bits_for(n, require_sign_bit=False):
if require_sign_bit:
r += 1
return r


def deprecated(message, stacklevel=2):
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
warnings.warn(message, DeprecationWarning, stacklevel=stacklevel)
return f(*args, **kwargs)
return wrapper
return decorator