Remove everything deprecated in nmigen 0.1.

Closes #275.
This commit is contained in:
whitequark 2020-01-12 13:59:26 +00:00
parent e4e26717be
commit e18385b613
13 changed files with 208 additions and 240 deletions

View file

@ -17,5 +17,4 @@ __all__ = [
"Memory",
"Record",
"DomainRenamer", "ResetInserter", "EnableInserter",
"CEInserter", # TODO(nmigen-0.2): remove this
]

View file

@ -7,6 +7,7 @@ from ...hdl.mem import Memory as NativeMemory
from ...hdl.ir import Fragment, Instance
from ...hdl.dsl import Module
from .module import Module as CompatModule
from .structure import Signal
from ...lib.io import Pin

View file

@ -1,8 +1,14 @@
import builtins
import warnings
from collections import OrderedDict
from ...utils import bits_for
from ..._utils import deprecated, extend
from ...hdl import ast
from ...hdl.ast import (DUID, Value, Signal, Mux, Slice as _Slice, Cat, Repl, Const, C,
from ...hdl.ast import (DUID,
Shape, signed, unsigned,
Value, Const, C, Mux, Slice as _Slice, Part, Cat, Repl,
Signal as NativeSignal,
ClockSignal, ResetSignal,
Array, ArrayProxy as _ArrayProxy)
from ...hdl.cd import ClockDomain
@ -17,11 +23,47 @@ def wrap(v):
return Value.cast(v)
@extend(Cat)
@property
@deprecated("instead of `Cat.l`, use `Cat.parts`")
def l(self):
return self.parts
class CompatSignal(NativeSignal):
def __init__(self, bits_sign=None, name=None, variable=False, reset=0,
reset_less=False, name_override=None, min=None, max=None,
related=None, attr=None, src_loc_at=0, **kwargs):
if min is not None or max is not None:
warnings.warn("instead of `Signal(min={min}, max={max})`, "
"use `Signal(range({min}, {max}))`"
.format(min=min or 0, max=max or 2),
DeprecationWarning, stacklevel=2 + src_loc_at)
if bits_sign is None:
if min is None:
min = 0
if max is None:
max = 2
max -= 1 # make both bounds inclusive
if min > max:
raise ValueError("Lower bound {} should be less or equal to higher bound {}"
.format(min, max + 1))
sign = min < 0 or max < 0
if min == max:
bits = 0
else:
bits = builtins.max(bits_for(min, sign), bits_for(max, sign))
shape = signed(bits) if sign else unsigned(bits)
else:
if not (min is None and max is None):
raise ValueError("Only one of bits/signedness or bounds may be specified")
shape = bits_sign
super().__init__(shape=shape, name=name_override or name,
reset=reset, reset_less=reset_less,
attrs=attr, src_loc_at=1 + src_loc_at, **kwargs)
Signal = CompatSignal
@deprecated("instead of `Constant`, use `Const`")
def Constant(value, bits_sign=None):
return Const(value, bits_sign)
@deprecated("instead of `Replicate`, use `Repl`")
@ -29,9 +71,45 @@ 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)
@extend(Const)
@property
@deprecated("instead of `.nbits`, use `.width`")
def nbits(self):
return self.width
@extend(NativeSignal)
@property
@deprecated("instead of `.nbits`, use `.width`")
def nbits(self):
return self.width
@extend(NativeSignal)
@NativeSignal.nbits.setter
@deprecated("instead of `.nbits = x`, use `.width = x`")
def nbits(self, value):
self.width = value
@extend(NativeSignal)
@deprecated("instead of `.part`, use `.bit_select`")
def part(self, offset, width):
return Part(self, offset, width, src_loc_at=2)
@extend(Cat)
@property
@deprecated("instead of `.l`, use `.parts`")
def l(self):
return self.parts
@extend(ast.Operator)
@property
@deprecated("instead of `.op`, use `.operator`")
def op(self):
return self.operator
@extend(_ArrayProxy)
@ -47,7 +125,7 @@ class If(ast.Switch):
cond = Value.cast(cond)
if len(cond) != 1:
cond = cond.bool()
super().__init__(cond, {("1",): ast.Statement.wrap(stmts)})
super().__init__(cond, {("1",): ast.Statement.cast(stmts)})
@deprecated("instead of `.Elif(cond, ...)`, use `with m.Elif(cond): ...`")
def Elif(self, cond, *stmts):
@ -55,13 +133,13 @@ class If(ast.Switch):
if len(cond) != 1:
cond = cond.bool()
self.cases = OrderedDict((("-" + k,), v) for (k,), v in self.cases.items())
self.cases[("1" + "-" * len(self.test),)] = ast.Statement.wrap(stmts)
self.cases[("1" + "-" * len(self.test),)] = ast.Statement.cast(stmts)
self.test = Cat(self.test, cond)
return self
@deprecated("instead of `.Else(...)`, use `with m.Else(): ...`")
def Else(self, *stmts):
self.cases[()] = ast.Statement.wrap(stmts)
self.cases[()] = ast.Statement.cast(stmts)
return self
@ -100,7 +178,7 @@ class Case(ast.Switch):
elif isinstance(key, str) and key == "default":
key = ()
else:
key = ("{:0{}b}".format(wrap(key).value, len(self.test)),)
key = ("{:0{}b}".format(ast.Value.cast(key).value, len(self.test)),)
stmts = self.cases[key]
del self.cases[key]
self.cases[()] = stmts

View file

@ -14,6 +14,90 @@ class CompatFIFOInterface(NativeFIFOInterface):
del self.fwft
@extend(NativeFIFOInterface)
@property
@deprecated("instead of `fifo.din`, use `fifo.w_data`")
def din(self):
return self.w_data
@extend(NativeFIFOInterface)
@NativeFIFOInterface.din.setter
@deprecated("instead of `fifo.din = x`, use `fifo.w_data = x`")
def din(self, w_data):
self.w_data = w_data
@extend(NativeFIFOInterface)
@property
@deprecated("instead of `fifo.writable`, use `fifo.w_rdy`")
def writable(self):
return self.w_rdy
@extend(NativeFIFOInterface)
@NativeFIFOInterface.writable.setter
@deprecated("instead of `fifo.writable = x`, use `fifo.w_rdy = x`")
def writable(self, w_rdy):
self.w_rdy = w_rdy
@extend(NativeFIFOInterface)
@property
@deprecated("instead of `fifo.we`, use `fifo.w_en`")
def we(self):
return self.w_en
@extend(NativeFIFOInterface)
@NativeFIFOInterface.we.setter
@deprecated("instead of `fifo.we = x`, use `fifo.w_en = x`")
def we(self, w_en):
self.w_en = w_en
@extend(NativeFIFOInterface)
@property
@deprecated("instead of `fifo.dout`, use `fifo.r_data`")
def dout(self):
return self.r_data
@extend(NativeFIFOInterface)
@NativeFIFOInterface.dout.setter
@deprecated("instead of `fifo.dout = x`, use `fifo.r_data = x`")
def dout(self, r_data):
self.r_data = r_data
@extend(NativeFIFOInterface)
@property
@deprecated("instead of `fifo.readable`, use `fifo.r_rdy`")
def readable(self):
return self.r_rdy
@extend(NativeFIFOInterface)
@NativeFIFOInterface.readable.setter
@deprecated("instead of `fifo.readable = x`, use `fifo.r_rdy = x`")
def readable(self, r_rdy):
self.r_rdy = r_rdy
@extend(NativeFIFOInterface)
@property
@deprecated("instead of `fifo.re`, use `fifo.r_en`")
def re(self):
return self.r_en
@extend(NativeFIFOInterface)
@NativeFIFOInterface.re.setter
@deprecated("instead of `fifo.re = x`, use `fifo.r_en = x`")
def re(self, r_en):
self.r_en = r_en
@extend(NativeFIFOInterface)
def read(self):
"""Read method for simulation."""

View file

@ -3,8 +3,9 @@ from collections import OrderedDict
from ..._utils import deprecated, _ignore_deprecated
from ...hdl.xfrm import ValueTransformer, StatementTransformer
from ...hdl.ast import *
from ...hdl.ast import Signal as NativeSignal
from ..fhdl.module import CompatModule, CompatFinalizeError
from ..fhdl.structure import If, Case
from ..fhdl.structure import Signal, If, Case
__all__ = ["AnonymousState", "NextState", "NextValue", "FSM"]
@ -33,7 +34,7 @@ def _target_eq(a, b):
ty = type(a)
if ty == Const:
return a.value == b.value
elif ty == Signal:
elif ty == NativeSignal or ty == Signal:
return a is b
elif ty == Cat:
return all(_target_eq(x, y) for x, y in zip(a.l, b.l))
@ -164,7 +165,7 @@ class FSM(CompatModule):
self.decoding = {n: s for s, n in self.encoding.items()}
decoder = lambda n: "{}/{}".format(self.decoding[n], n)
self.state = Signal(max=nstates, reset=self.encoding[self.reset_state], decoder=decoder)
self.state = Signal(range(nstates), reset=self.encoding[self.reset_state], decoder=decoder)
self.next_state = Signal.like(self.state)
for state, signal in self.before_leaving_signals.items():

View file

@ -5,8 +5,7 @@ from .cd import ClockDomain
from .ir import Elaboratable, Fragment, Instance
from .mem import Memory
from .rec import Record
from .xfrm import DomainRenamer, ResetInserter, EnableInserter, \
CEInserter # TODO(nmigen-0.2): remove this
from .xfrm import DomainRenamer, ResetInserter, EnableInserter
__all__ = [
@ -18,5 +17,4 @@ __all__ = [
"Memory",
"Record",
"DomainRenamer", "ResetInserter", "EnableInserter",
"CEInserter", # TODO(nmigen-0.2): remove this
]

View file

@ -1,5 +1,4 @@
from abc import ABCMeta, abstractmethod
import builtins
import traceback
import warnings
import typing
@ -124,12 +123,6 @@ class Value(metaclass=ABCMeta):
return Const(obj.value, Shape.cast(type(obj)))
raise TypeError("Object {!r} cannot be converted to an nMigen value".format(obj))
# TODO(nmigen-0.2): remove this
@classmethod
@deprecated("instead of `Value.wrap`, use `Value.cast`")
def wrap(cls, obj):
return cls.cast(obj)
def __init__(self, *, src_loc_at=0):
super().__init__()
self.src_loc = tracer.get_src_loc(1 + src_loc_at)
@ -281,11 +274,6 @@ class Value(metaclass=ABCMeta):
"""
return ~premise | conclusion
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@deprecated("instead of `.part`, use `.bit_select`")
def part(self, offset, width):
return Part(self, offset, width, src_loc_at=1)
def bit_select(self, offset, width):
"""Part-select with bit granularity.
@ -471,12 +459,6 @@ class Const(Value):
self.width, self.signed = shape
self.value = self.normalize(self.value, shape)
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `const.nbits`, use `const.width`")
def nbits(self):
return self.width
def shape(self):
return Shape(self.width, self.signed)
@ -527,12 +509,6 @@ class Operator(Value):
self.operator = operator
self.operands = [Value.cast(op) for op in operands]
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `.op`, use `.operator`")
def op(self):
return self.operator
def shape(self):
def _bitwise_binary_shape(a_shape, b_shape):
a_bits, a_sign = a_shape
@ -644,13 +620,7 @@ class Slice(Value):
super().__init__(src_loc_at=src_loc_at)
self.value = Value.cast(value)
self.start = start
self.stop = stop
# TODO(nmigen-0.2): remove this
@property
@deprecated("instead of `slice.end`, use `slice.stop`")
def end(self):
return self.stop
self.stop = stop
def shape(self):
return Shape(self.stop - self.start)
@ -782,7 +752,7 @@ class Repl(Value):
return "(repl {!r} {})".format(self.value, self.count)
@final
# @final
class Signal(Value, DUID):
"""A varying integer value.
@ -830,46 +800,22 @@ class Signal(Value, DUID):
attrs : dict
"""
def __init__(self, shape=None, *, name=None, reset=0, reset_less=False, min=None, max=None,
def __init__(self, shape=None, *, name=None, reset=0, reset_less=False,
attrs=None, decoder=None, src_loc_at=0):
super().__init__(src_loc_at=src_loc_at)
if isinstance(reset, Enum):
reset = reset.value
if not isinstance(reset, int):
raise TypeError("Reset value has to be an int or an integral Enum")
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
if min is not None or max is not None:
warnings.warn("instead of `Signal(min={min}, max={max})`, "
"use `Signal(range({min}, {max}))`"
.format(min=min or 0, max=max or 2),
DeprecationWarning, stacklevel=2 + src_loc_at)
if name is not None and not isinstance(name, str):
raise TypeError("Name must be a string, not {!r}".format(name))
self.name = name or tracer.get_var_name(depth=2 + src_loc_at, default="$signal")
if shape is None:
if min is None:
min = 0
if max is None:
max = 2
max -= 1 # make both bounds inclusive
if min > max:
raise ValueError("Lower bound {} should be less or equal to higher bound {}"
.format(min, max + 1))
self.signed = min < 0 or max < 0
if min == max:
self.width = 0
else:
self.width = builtins.max(bits_for(min, self.signed),
bits_for(max, self.signed))
shape = unsigned(1)
self.width, self.signed = Shape.cast(shape, src_loc_at=1 + src_loc_at)
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, src_loc_at=1 + src_loc_at)
if isinstance(reset, Enum):
reset = reset.value
if not isinstance(reset, int):
raise TypeError("Reset value has to be an int or an integral Enum")
reset_width = bits_for(reset, self.signed)
if reset != 0 and reset_width > self.width:
@ -878,7 +824,7 @@ class Signal(Value, DUID):
.format(reset, reset_width, self.width),
SyntaxWarning, stacklevel=2 + src_loc_at)
self.reset = int(reset)
self.reset = reset
self.reset_less = bool(reset_less)
self.attrs = OrderedDict(() if attrs is None else attrs)
@ -895,20 +841,9 @@ class Signal(Value, DUID):
else:
self.decoder = decoder
@classmethod
@deprecated("instead of `Signal.range(...)`, use `Signal(range(...))`")
def range(cls, *args, src_loc_at=0, **kwargs):
return cls(range(*args), src_loc_at=2 + src_loc_at, **kwargs)
@classmethod
@deprecated("instead of `Signal.enum(...)`, use `Signal(...)`")
def enum(cls, enum_type, *, src_loc_at=0, **kwargs):
if not issubclass(enum_type, Enum):
raise TypeError("Type {!r} is not an enumeration")
return cls(enum_type, src_loc_at=2 + src_loc_at, **kwargs)
@classmethod
def like(cls, other, *, name=None, name_suffix=None, src_loc_at=0, **kwargs):
# Not a @classmethod because nmigen.compat requires it.
@staticmethod
def like(other, *, name=None, name_suffix=None, src_loc_at=0, **kwargs):
"""Create Signal based on another.
Parameters
@ -922,23 +857,12 @@ class Signal(Value, DUID):
new_name = other.name + str(name_suffix)
else:
new_name = tracer.get_var_name(depth=2 + src_loc_at, default="$like")
kw = dict(shape=cls.cast(other).shape(), name=new_name)
if isinstance(other, cls):
kw = dict(shape=Value.cast(other).shape(), name=new_name)
if isinstance(other, Signal):
kw.update(reset=other.reset, reset_less=other.reset_less,
attrs=other.attrs, decoder=other.decoder)
kw.update(kwargs)
return cls(**kw, src_loc_at=1 + src_loc_at)
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `signal.nbits`, use `signal.width`")
def nbits(self):
return self.width
@nbits.setter
@deprecated("instead of `signal.nbits = x`, use `signal.width = x`")
def nbits(self, value):
self.width = value
return Signal(**kw, src_loc_at=1 + src_loc_at)
def shape(self):
return Shape(self.width, self.signed)
@ -1269,12 +1193,6 @@ 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 cast(obj):
if isinstance(obj, Iterable):
@ -1507,7 +1425,7 @@ class ValueKey:
self._hash = hash((self.value.operator,
tuple(ValueKey(o) for o in self.value.operands)))
elif isinstance(self.value, Slice):
self._hash = hash((ValueKey(self.value.value), self.value.start, self.value.end))
self._hash = hash((ValueKey(self.value.value), self.value.start, self.value.stop))
elif isinstance(self.value, Part):
self._hash = hash((ValueKey(self.value.value), ValueKey(self.value.offset),
self.value.width, self.value.stride))
@ -1547,7 +1465,7 @@ class ValueKey:
elif isinstance(self.value, Slice):
return (ValueKey(self.value.value) == ValueKey(other.value.value) and
self.value.start == other.value.start and
self.value.end == other.value.end)
self.value.stop == other.value.stop)
elif isinstance(self.value, Part):
return (ValueKey(self.value.value) == ValueKey(other.value.value) and
ValueKey(self.value.offset) == ValueKey(other.value.offset) and
@ -1606,7 +1524,7 @@ class ValueSet(_MappedKeySet):
class SignalKey:
def __init__(self, signal):
self.signal = signal
if type(signal) is Signal:
if isinstance(signal, Signal):
self._intern = (0, signal.duid)
elif type(signal) is ClockSignal:
self._intern = (1, signal.domain)

View file

@ -24,12 +24,6 @@ class Layout:
return obj
return Layout(obj, src_loc_at=1 + src_loc_at)
# 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:

View file

@ -18,7 +18,7 @@ __all__ = ["ValueVisitor", "ValueTransformer",
"DomainCollector", "DomainRenamer", "DomainLowerer",
"SampleDomainInjector", "SampleLowerer",
"SwitchCleaner", "LHSGroupAnalyzer", "LHSGroupFilter",
"ResetInserter", "EnableInserter", "CEInserter"]
"ResetInserter", "EnableInserter"]
class ValueVisitor(metaclass=ABCMeta):
@ -95,7 +95,8 @@ class ValueVisitor(metaclass=ABCMeta):
new_value = self.on_AnyConst(value)
elif type(value) is AnySeq:
new_value = self.on_AnySeq(value)
elif type(value) is Signal:
elif isinstance(value, Signal):
# Uses `isinstance()` and not `type() is` because nmigen.compat requires it.
new_value = self.on_Signal(value)
elif isinstance(value, Record):
# Uses `isinstance()` and not `type() is` to allow inheriting from Record.
@ -110,8 +111,7 @@ class ValueVisitor(metaclass=ABCMeta):
new_value = self.on_Slice(value)
elif type(value) is Part:
new_value = self.on_Part(value)
elif isinstance(value, Cat):
# Uses `isinstance()` and not `type() is` because nmigen.compat requires it.
elif type(value) is Cat:
new_value = self.on_Cat(value)
elif type(value) is Repl:
new_value = self.on_Repl(value)
@ -750,7 +750,3 @@ class EnableInserter(_ControlInserter):
en_port = Mux(self.controls[clk_port.domain], en_port, Const(0, len(en_port)))
new_fragment.named_ports["EN"] = en_port, en_dir
return new_fragment
CEInserter = staticmethod(
deprecated("instead of `CEInserter`, use `EnableInserter`")(EnableInserter))

View file

@ -3,8 +3,6 @@ from .. import *
__all__ = ["FFSynchronizer", "ResetSynchronizer"]
# TODO(nmigen-0.2): remove this
__all__ += ["MultiReg"]
def _check_stages(stages):
@ -97,10 +95,6 @@ class FFSynchronizer(Elaboratable):
return m
# TODO(nmigen-0.2): remove this
MultiReg = deprecated("instead of `MultiReg`, use `FFSynchronizer`")(FFSynchronizer)
class ResetSynchronizer(Elaboratable):
"""Synchronize deassertion of a clock domain reset.

View file

@ -79,78 +79,6 @@ class FIFOInterface:
self.r_rdy = Signal() # readable; not empty
self.r_en = Signal()
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `fifo.din`, use `fifo.w_data`")
def din(self):
return self.w_data
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@din.setter
@deprecated("instead of `fifo.din = x`, use `fifo.w_data = x`")
def din(self, w_data):
self.w_data = w_data
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `fifo.writable`, use `fifo.w_rdy`")
def writable(self):
return self.w_rdy
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@writable.setter
@deprecated("instead of `fifo.writable = x`, use `fifo.w_rdy = x`")
def writable(self, w_rdy):
self.w_rdy = w_rdy
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `fifo.we`, use `fifo.w_en`")
def we(self):
return self.w_en
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@we.setter
@deprecated("instead of `fifo.we = x`, use `fifo.w_en = x`")
def we(self, w_en):
self.w_en = w_en
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `fifo.dout`, use `fifo.r_data`")
def dout(self):
return self.r_data
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@dout.setter
@deprecated("instead of `fifo.dout = x`, use `fifo.r_data = x`")
def dout(self, r_data):
self.r_data = r_data
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `fifo.readable`, use `fifo.r_rdy`")
def readable(self):
return self.r_rdy
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@readable.setter
@deprecated("instead of `fifo.readable = x`, use `fifo.r_rdy = x`")
def readable(self, r_rdy):
self.r_rdy = r_rdy
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@property
@deprecated("instead of `fifo.re`, use `fifo.r_en`")
def re(self):
return self.r_en
# TODO(nmigen-0.2): move this to nmigen.compat and make it a deprecated extension
@re.setter
@deprecated("instead of `fifo.re = x`, use `fifo.r_en = x`")
def re(self, r_en):
self.r_en = r_en
def _incr(signal, modulo):
if modulo == 2 ** len(signal):

View file

@ -712,38 +712,12 @@ class SignalTestCase(FHDLTestCase):
self.assertEqual(s10.shape(), unsigned(0))
s11 = Signal(range(1))
self.assertEqual(s11.shape(), unsigned(1))
# deprecated
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
d6 = Signal(max=16)
self.assertEqual(d6.shape(), unsigned(4))
d7 = Signal(min=4, max=16)
self.assertEqual(d7.shape(), unsigned(4))
d8 = Signal(min=-4, max=16)
self.assertEqual(d8.shape(), signed(5))
d9 = Signal(min=-20, max=16)
self.assertEqual(d9.shape(), signed(6))
d10 = Signal(max=1)
self.assertEqual(d10.shape(), unsigned(0))
def test_shape_wrong(self):
with self.assertRaises(TypeError,
msg="Width must be a non-negative integer, not -10"):
Signal(-10)
def test_min_max_deprecated(self):
with self.assertWarns(DeprecationWarning,
msg="instead of `Signal(min=0, max=10)`, use `Signal(range(0, 10))`"):
Signal(max=10)
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
with self.assertRaises(ValueError,
msg="Lower bound 10 should be less or equal to higher bound 4"):
Signal(min=10, max=4)
with self.assertRaises(ValueError,
msg="Only one of bits/signedness or bounds may be specified"):
Signal(2, min=10)
def test_name(self):
s1 = Signal()
self.assertEqual(s1.name, "s1")

View file

@ -350,16 +350,18 @@ class LatticeICE40Platform(TemplatedPlatform):
rst_i = Const(0)
m = Module()
# Power-on-reset domain
m.domains += ClockDomain("por", reset_less=True, local=True)
delay = int(15e-6 * self.default_clk_frequency)
timer = Signal(max=delay)
timer = Signal(range(delay))
ready = Signal()
m.d.comb += ClockSignal("por").eq(clk_i)
with m.If(timer == delay):
m.d.por += ready.eq(1)
with m.Else():
m.d.por += timer.eq(timer + 1)
# Primary domain
m.domains += ClockDomain("sync")
m.d.comb += ClockSignal("sync").eq(clk_i)
@ -367,6 +369,7 @@ class LatticeICE40Platform(TemplatedPlatform):
m.submodules.reset_sync = ResetSynchronizer(~ready | rst_i, domain="sync")
else:
m.d.comb += ResetSignal("sync").eq(~ready)
return m
def should_skip_port_component(self, port, attrs, component):