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: 706bfaf5e185
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: b90687c98838
Choose a head ref
  • 2 commits
  • 10 files changed
  • 1 contributor

Commits on Oct 11, 2019

  1. hdl.ast: deprecate shapes like (1, True) in favor of signed(1).

    This is a great improvement in clarity.
    whitequark committed Oct 11, 2019
    Copy the full SHA
    a658cb2 View commit details
  2. Rename remaining wrap methods to cast.

    Following commit d72d4a5.
    whitequark committed Oct 11, 2019
    Copy the full SHA
    b90687c View commit details
Showing with 221 additions and 191 deletions.
  1. +2 −2 nmigen/back/rtlil.py
  2. +22 −9 nmigen/hdl/ast.py
  3. +2 −2 nmigen/hdl/dsl.py
  4. +1 −1 nmigen/hdl/ir.py
  5. +13 −7 nmigen/hdl/rec.py
  6. +3 −1 nmigen/test/compat/test_size.py
  7. +165 −156 nmigen/test/test_hdl_ast.py
  8. +11 −11 nmigen/test/test_hdl_rec.py
  9. +1 −1 nmigen/test/test_sim.py
  10. +1 −1 nmigen/test/tools.py
4 changes: 2 additions & 2 deletions nmigen/back/rtlil.py
Original file line number Diff line number Diff line change
@@ -464,7 +464,7 @@ def on_Operator_unary(self, value):

def match_shape(self, value, new_bits, new_sign):
if isinstance(value, ast.Const):
return self(ast.Const(value.value, (new_bits, new_sign)))
return self(ast.Const(value.value, ast.Shape(new_bits, new_sign)))

value_bits, value_sign = value.shape()
if new_bits <= value_bits:
@@ -511,7 +511,7 @@ def on_Operator_binary(self, value):
res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
self.s.rtlil.cell("$mux", ports={
"\\A": divmod_res,
"\\B": self(ast.Const(0, (res_bits, res_sign))),
"\\B": self(ast.Const(0, ast.Shape(res_bits, res_sign))),
"\\S": self(lhs == 0),
"\\Y": res,
}, params={
31 changes: 22 additions & 9 deletions nmigen/hdl/ast.py
Original file line number Diff line number Diff line change
@@ -59,11 +59,18 @@ class Shape(typing.NamedTuple):
signed: bool = False

@staticmethod
def cast(obj):
def cast(obj, *, src_loc_at=0):
if isinstance(obj, Shape):
return obj
if isinstance(obj, int):
return Shape(obj)
if isinstance(obj, tuple):
return Shape(*obj)
width, signed = obj
warnings.warn("instead of `{tuple}`, use `{constructor}({width})`"
.format(constructor="signed" if signed else "unsigned", width=width,
tuple=obj),
DeprecationWarning, stacklevel=2 + src_loc_at)
return Shape(width, signed)
if isinstance(obj, range):
if len(obj) == 0:
return Shape(0, obj.start < 0)
@@ -446,15 +453,15 @@ def normalize(value, shape):
value |= ~mask
return value

def __init__(self, value, shape=None):
def __init__(self, value, shape=None, *, src_loc_at=0):
# We deliberately do not call Value.__init__ here.
self.value = int(value)
if shape is None:
shape = Shape(bits_for(self.value), signed=self.value < 0)
elif isinstance(shape, int):
shape = Shape(shape, signed=self.value < 0)
else:
shape = Shape.cast(shape)
shape = Shape.cast(shape, src_loc_at=1 + src_loc_at)
self.width, self.signed = shape
self.value = self.normalize(self.value, shape)

@@ -483,7 +490,7 @@ def __repr__(self):
class AnyValue(Value, DUID):
def __init__(self, shape, *, src_loc_at=0):
super().__init__(src_loc_at=src_loc_at)
self.width, self.signed = Shape.cast(shape)
self.width, self.signed = Shape.cast(shape, src_loc_at=1 + src_loc_at)
if not isinstance(self.width, int) or self.width < 0:
raise TypeError("Width must be a non-negative integer, not {!r}"
.format(self.width))
@@ -848,7 +855,7 @@ def __init__(self, shape=None, *, name=None, reset=0, reset_less=False, min=None
else:
if not (min is None and max is None):
raise ValueError("Only one of bits/signedness or bounds may be specified")
self.width, self.signed = Shape.cast(shape)
self.width, self.signed = Shape.cast(shape, src_loc_at=1 + src_loc_at)

reset_width = bits_for(reset, self.signed)
if reset != 0 and reset_width > self.width:
@@ -1248,10 +1255,16 @@ class Statement:
def __init__(self, *, src_loc_at=0):
self.src_loc = tracer.get_src_loc(1 + src_loc_at)

# TODO(nmigen-0.2): remove this
@classmethod
@deprecated("instead of `Statement.wrap`, use `Statement.cast`")
def wrap(cls, obj):
return cls.cast(obj)

@staticmethod
def wrap(obj):
def cast(obj):
if isinstance(obj, Iterable):
return _StatementList(sum((Statement.wrap(e) for e in obj), []))
return _StatementList(sum((Statement.cast(e) for e in obj), []))
else:
if isinstance(obj, Statement):
return _StatementList([obj])
@@ -1352,7 +1365,7 @@ def __init__(self, test, cases, *, src_loc=None, src_loc_at=0, case_src_locs={})
new_keys = (*new_keys, key)
if not isinstance(stmts, Iterable):
stmts = [stmts]
self.cases[new_keys] = Statement.wrap(stmts)
self.cases[new_keys] = Statement.cast(stmts)
if orig_keys in case_src_locs:
self.case_src_locs[new_keys] = case_src_locs[orig_keys]

4 changes: 2 additions & 2 deletions nmigen/hdl/dsl.py
Original file line number Diff line number Diff line change
@@ -131,7 +131,7 @@ def __init__(self):
self.submodules = _ModuleBuilderSubmodules(self)
self.domains = _ModuleBuilderDomainSet(self)

self._statements = Statement.wrap([])
self._statements = Statement.cast([])
self._ctrl_context = None
self._ctrl_stack = []

@@ -433,7 +433,7 @@ def domain_name(domain):
while len(self._ctrl_stack) > self.domain._depth:
self._pop_ctrl()

for assign in Statement.wrap(assigns):
for assign in Statement.cast(assigns):
if not compat_mode and not isinstance(assign, (Assign, Assert, Assume, Cover)):
raise SyntaxError(
"Only assignments and property checks may be appended to d.{}"
2 changes: 1 addition & 1 deletion nmigen/hdl/ir.py
Original file line number Diff line number Diff line change
@@ -144,7 +144,7 @@ def iter_domains(self):
yield from self.domains

def add_statements(self, *stmts):
self.statements += Statement.wrap(stmts)
self.statements += Statement.cast(stmts)

def add_subfragment(self, subfragment, name=None):
assert isinstance(subfragment, Fragment)
20 changes: 13 additions & 7 deletions nmigen/hdl/rec.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
from functools import reduce

from .. import tracer
from ..tools import union
from ..tools import union, deprecated
from .ast import *


@@ -19,12 +19,18 @@

class Layout:
@staticmethod
def wrap(obj):
def cast(obj, *, src_loc_at=0):
if isinstance(obj, Layout):
return obj
return Layout(obj)
return Layout(obj, src_loc_at=1 + src_loc_at)

def __init__(self, fields):
# TODO(nmigen-0.2): remove this
@classmethod
@deprecated("instead of `Layout.wrap`, use `Layout.cast`")
def wrap(cls, obj, *, src_loc_at=0):
return cls.cast(obj, src_loc_at=1 + src_loc_at)

def __init__(self, fields, *, src_loc_at=0):
self.fields = OrderedDict()
for field in fields:
if not isinstance(field, tuple) or len(field) not in (2, 3):
@@ -35,7 +41,7 @@ def __init__(self, fields):
name, shape = field
direction = DIR_NONE
if isinstance(shape, list):
shape = Layout.wrap(shape)
shape = Layout.cast(shape)
else:
name, shape, direction = field
if not isinstance(direction, Direction):
@@ -47,7 +53,7 @@ def __init__(self, fields):
.format(field))
if not isinstance(shape, Layout):
try:
shape = Shape.cast(shape)
shape = Shape.cast(shape, src_loc_at=1 + src_loc_at)
except Exception as error:
raise TypeError("Field {!r} has invalid shape: should be castable to Shape "
"or a list of fields of a nested record"
@@ -115,7 +121,7 @@ def concat(a, b):
return b
return "{}__{}".format(a, b)

self.layout = Layout.wrap(layout)
self.layout = Layout.cast(layout, src_loc_at=1 + src_loc_at)
self.fields = OrderedDict()
for field_name, field_shape, field_dir in self.layout:
if fields is not None and field_name in fields:
4 changes: 3 additions & 1 deletion nmigen/test/compat/test_size.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest

from ...tools import _ignore_deprecated
from ...compat import *


@@ -11,7 +12,8 @@ class SignalSizeCase(unittest.TestCase):
def setUp(self):
self.i = C(0xaa)
self.j = C(-127)
self.s = Signal((13, True))
with _ignore_deprecated():
self.s = Signal((13, True))

def test_len(self):
self.assertEqual(len(self.s), 13)
Loading