Skip to content

Commit 24a3928

Browse files
wanda-phiwhitequark
authored andcommitted
Implement RFC 43: Rename reset= to init=.
1 parent b30c87f commit 24a3928

30 files changed

+475
-275
lines changed

amaranth/hdl/_ast.py

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,15 @@ class ShapeCastable:
173173
174174
.. code::
175175
176-
value_like = Signal(shape_castable, reset=initializer)
176+
value_like = Signal(shape_castable, init=initializer)
177177
178178
The code above is equivalent to:
179179
180180
.. code::
181181
182182
value_like = shape_castable(Signal(
183183
shape_castable.as_shape(),
184-
reset=shape_castable.const(initializer)
184+
init=shape_castable.const(initializer)
185185
))
186186
187187
Note that the :py:`shape_castable(x)` syntax performs :py:`shape_castable.__call__(x)`.
@@ -1731,15 +1731,15 @@ class Signal(Value, DUID, metaclass=_SignalMeta):
17311731
name : str
17321732
Name hint for this signal. If ``None`` (default) the name is inferred from the variable
17331733
name this ``Signal`` is assigned to.
1734-
reset : int or integral Enum
1734+
init : int or integral Enum
17351735
Reset (synchronous) or default (combinatorial) value.
17361736
When this ``Signal`` is assigned to in synchronous context and the corresponding clock
17371737
domain is reset, the ``Signal`` assumes the given value. When this ``Signal`` is unassigned
17381738
in combinatorial context (due to conditional assignments not being taken), the ``Signal``
1739-
assumes its ``reset`` value. Defaults to 0.
1739+
assumes its ``init`` value. Defaults to 0.
17401740
reset_less : bool
17411741
If ``True``, do not generate reset logic for this ``Signal`` in synchronous statements.
1742-
The ``reset`` value is only used as a combinatorial default or as the initial value.
1742+
The ``init`` value is only used as a combinatorial default or as the initial value.
17431743
Defaults to ``False``.
17441744
attrs : dict
17451745
Dictionary of synthesis attributes.
@@ -1754,13 +1754,13 @@ class Signal(Value, DUID, metaclass=_SignalMeta):
17541754
width : int
17551755
signed : bool
17561756
name : str
1757-
reset : int
1757+
init : int
17581758
reset_less : bool
17591759
attrs : dict
17601760
decoder : function
17611761
"""
17621762

1763-
def __init__(self, shape=None, *, name=None, reset=None, reset_less=False,
1763+
def __init__(self, shape=None, *, name=None, init=None, reset=None, reset_less=False,
17641764
attrs=None, decoder=None, src_loc_at=0):
17651765
super().__init__(src_loc_at=src_loc_at)
17661766

@@ -1776,53 +1776,61 @@ def __init__(self, shape=None, *, name=None, reset=None, reset_less=False,
17761776
self.width = shape.width
17771777
self.signed = shape.signed
17781778

1779-
orig_reset = reset
1779+
# TODO(amaranth-0.7): remove
1780+
if reset is not None:
1781+
if init is not None:
1782+
raise ValueError("Cannot specify both `reset` and `init`")
1783+
warnings.warn("`reset=` is deprecated, use `init=` instead",
1784+
DeprecationWarning, stacklevel=2)
1785+
init = reset
1786+
1787+
orig_init = init
17801788
if isinstance(orig_shape, ShapeCastable):
17811789
try:
1782-
reset = Const.cast(orig_shape.const(reset))
1790+
init = Const.cast(orig_shape.const(init))
17831791
except Exception:
1784-
raise TypeError("Reset value must be a constant initializer of {!r}"
1792+
raise TypeError("Initial value must be a constant initializer of {!r}"
17851793
.format(orig_shape))
1786-
if reset.shape() != Shape.cast(orig_shape):
1794+
if init.shape() != Shape.cast(orig_shape):
17871795
raise ValueError("Constant returned by {!r}.const() must have the shape that "
17881796
"it casts to, {!r}, and not {!r}"
17891797
.format(orig_shape, Shape.cast(orig_shape),
1790-
reset.shape()))
1798+
init.shape()))
17911799
else:
1792-
if reset is None:
1793-
reset = 0
1800+
if init is None:
1801+
init = 0
17941802
try:
1795-
reset = Const.cast(reset)
1803+
init = Const.cast(init)
17961804
except TypeError:
1797-
raise TypeError("Reset value must be a constant-castable expression, not {!r}"
1798-
.format(orig_reset))
1805+
raise TypeError("Initial value must be a constant-castable expression, not {!r}"
1806+
.format(orig_init))
17991807
# Avoid false positives for all-zeroes and all-ones
1800-
if orig_reset is not None and not (isinstance(orig_reset, int) and orig_reset in (0, -1)):
1801-
if reset.shape().signed and not self.signed:
1808+
if orig_init is not None and not (isinstance(orig_init, int) and orig_init in (0, -1)):
1809+
if init.shape().signed and not self.signed:
18021810
warnings.warn(
1803-
message="Reset value {!r} is signed, but the signal shape is {!r}"
1804-
.format(orig_reset, shape),
1811+
message="Initial value {!r} is signed, but the signal shape is {!r}"
1812+
.format(orig_init, shape),
18051813
category=SyntaxWarning,
18061814
stacklevel=2)
1807-
elif (reset.shape().width > self.width or
1808-
reset.shape().width == self.width and
1809-
self.signed and not reset.shape().signed):
1815+
elif (init.shape().width > self.width or
1816+
init.shape().width == self.width and
1817+
self.signed and not init.shape().signed):
18101818
warnings.warn(
1811-
message="Reset value {!r} will be truncated to the signal shape {!r}"
1812-
.format(orig_reset, shape),
1819+
message="Initial value {!r} will be truncated to the signal shape {!r}"
1820+
.format(orig_init, shape),
18131821
category=SyntaxWarning,
18141822
stacklevel=2)
1815-
self.reset = reset.value
1823+
self.init = init.value
18161824
self.reset_less = bool(reset_less)
18171825

1818-
if isinstance(orig_shape, range) and orig_reset is not None and orig_reset not in orig_shape:
1819-
if orig_reset == orig_shape.stop:
1826+
if isinstance(orig_shape, range) and orig_init is not None and orig_init not in orig_shape:
1827+
if orig_init == orig_shape.stop:
18201828
raise SyntaxError(
1821-
f"Reset value {orig_reset!r} equals the non-inclusive end of the signal "
1829+
f"Initial value {orig_init!r} equals the non-inclusive end of the signal "
18221830
f"shape {orig_shape!r}; this is likely an off-by-one error")
18231831
else:
18241832
raise SyntaxError(
1825-
f"Reset value {orig_reset!r} is not within the signal shape {orig_shape!r}")
1833+
f"Initial value {orig_init!r} is not within the signal shape {orig_shape!r}")
18261834

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

@@ -1850,6 +1858,18 @@ def __init__(self, shape=None, *, name=None, reset=None, reset_less=False,
18501858
# Any other case is formatted as a plain integer.
18511859
self._value_repr = (Repr(FormatInt(), self),)
18521860

1861+
@property
1862+
def reset(self):
1863+
warnings.warn("`Signal.reset` is deprecated, use `Signal.init` instead",
1864+
DeprecationWarning, stacklevel=2)
1865+
return self.init
1866+
1867+
@reset.setter
1868+
def reset(self, value):
1869+
warnings.warn("`Signal.reset` is deprecated, use `Signal.init` instead",
1870+
DeprecationWarning, stacklevel=2)
1871+
self.init = value
1872+
18531873
@property
18541874
def decoder(self):
18551875
return self._decoder
@@ -1873,7 +1893,7 @@ def enum_decoder(value):
18731893
self._decoder = enum_decoder
18741894

18751895
@classmethod
1876-
def like(cls, other, *, name=None, name_suffix=None, src_loc_at=0, **kwargs):
1896+
def like(cls, other, *, name=None, name_suffix=None, init=None, reset=None, src_loc_at=0, **kwargs):
18771897
"""Create Signal based on another.
18781898
18791899
Parameters
@@ -1887,15 +1907,24 @@ def like(cls, other, *, name=None, name_suffix=None, src_loc_at=0, **kwargs):
18871907
new_name = other.name + str(name_suffix)
18881908
else:
18891909
new_name = tracer.get_var_name(depth=2 + src_loc_at, default="$like")
1910+
# TODO(amaranth-0.7): remove
1911+
if reset is not None:
1912+
if init is not None:
1913+
raise ValueError("Cannot specify both `reset` and `init`")
1914+
warnings.warn("`reset=` is deprecated, use `init=` instead",
1915+
DeprecationWarning, stacklevel=2)
1916+
init = reset
18901917
if isinstance(other, ValueCastable):
18911918
shape = other.shape()
18921919
else:
18931920
shape = Value.cast(other).shape()
18941921
kw = dict(shape=shape, name=new_name)
18951922
if isinstance(other, Signal):
1896-
kw.update(reset=other.reset, reset_less=other.reset_less,
1923+
kw.update(init=other.init, reset_less=other.reset_less,
18971924
attrs=other.attrs, decoder=other.decoder)
18981925
kw.update(kwargs)
1926+
if init is not None:
1927+
kw["init"] = init
18991928
return cls(**kw, src_loc_at=1 + src_loc_at)
19001929

19011930
def shape(self):

amaranth/hdl/_dsl.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,21 @@ def Default(self):
374374
self._statements = _outer_case
375375

376376
@contextmanager
377-
def FSM(self, reset=None, domain="sync", name="fsm"):
377+
def FSM(self, init=None, domain="sync", name="fsm", *, reset=None):
378378
self._check_context("FSM", context=None)
379379
if domain == "comb":
380380
raise ValueError(f"FSM may not be driven by the '{domain}' domain")
381+
# TODO(amaranth-0.7): remove
382+
if reset is not None:
383+
if init is not None:
384+
raise ValueError("Cannot specify both `reset` and `init`")
385+
warnings.warn("`reset=` is deprecated, use `init=` instead",
386+
DeprecationWarning, stacklevel=2)
387+
init = reset
381388
fsm_data = self._set_ctrl("FSM", {
382389
"name": name,
383390
"signal": Signal(name=f"{name}_state", src_loc_at=2),
384-
"reset": reset,
391+
"init": init,
385392
"domain": domain,
386393
"encoding": OrderedDict(),
387394
"decoding": OrderedDict(),
@@ -489,17 +496,17 @@ def _pop_ctrl(self):
489496
src_loc=src_loc, case_src_locs=switch_case_src_locs))
490497

491498
if name == "FSM":
492-
fsm_signal, fsm_reset, fsm_encoding, fsm_decoding, fsm_states = \
493-
data["signal"], data["reset"], data["encoding"], data["decoding"], data["states"]
499+
fsm_signal, fsm_init, fsm_encoding, fsm_decoding, fsm_states = \
500+
data["signal"], data["init"], data["encoding"], data["decoding"], data["states"]
494501
fsm_state_src_locs = data["state_src_locs"]
495502
if not fsm_states:
496503
return
497504
fsm_signal.width = bits_for(len(fsm_encoding) - 1)
498-
if fsm_reset is None:
499-
fsm_signal.reset = fsm_encoding[next(iter(fsm_states))]
505+
if fsm_init is None:
506+
fsm_signal.init = fsm_encoding[next(iter(fsm_states))]
500507
else:
501-
fsm_signal.reset = fsm_encoding[fsm_reset]
502-
# The FSM is encoded such that the state with encoding 0 is always the reset state.
508+
fsm_signal.init = fsm_encoding[fsm_init]
509+
# The FSM is encoded such that the state with encoding 0 is always the init state.
503510
fsm_decoding.update((n, s) for s, n in fsm_encoding.items())
504511
fsm_signal.decoder = lambda n: f"{fsm_decoding[n]}/{n}"
505512

amaranth/hdl/_ir.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,8 @@ def __init__(self, module_idx: int, signal: _ast.Signal,
691691

692692
def emit_value(self, builder):
693693
if self.domain is None:
694-
reset = _ast.Const(self.signal.reset, self.signal.width)
695-
default, _signed = builder.emit_rhs(self.module_idx, reset)
694+
init = _ast.Const(self.signal.init, self.signal.width)
695+
default, _signed = builder.emit_rhs(self.module_idx, init)
696696
else:
697697
default = builder.emit_signal(self.signal)
698698
if len(self.assignments) == 1:
@@ -1184,7 +1184,7 @@ def emit_drivers(self):
11841184
arst = _nir.Net.from_const(0)
11851185
cell = _nir.FlipFlop(driver.module_idx,
11861186
data=value,
1187-
init=driver.signal.reset,
1187+
init=driver.signal.init,
11881188
clk=clk,
11891189
clk_edge=driver.domain.clk_edge,
11901190
arst=arst,
@@ -1198,12 +1198,12 @@ def emit_drivers(self):
11981198
src_loc = driver.signal.src_loc
11991199
self.connect(self.emit_signal(driver.signal), value, src_loc=src_loc)
12001200

1201-
# Connect all undriven signal bits to their reset values. This can only happen for entirely
1201+
# Connect all undriven signal bits to their initial values. This can only happen for entirely
12021202
# undriven signals, or signals that are partially driven by instances.
12031203
for signal, value in self.netlist.signals.items():
12041204
for bit, net in enumerate(value):
12051205
if net.is_late and net not in self.netlist.connections:
1206-
self.netlist.connections[net] = _nir.Net.from_const((signal.reset >> bit) & 1)
1206+
self.netlist.connections[net] = _nir.Net.from_const((signal.init >> bit) & 1)
12071207

12081208
def emit_fragment(self, fragment: _ir.Fragment, parent_module_idx: 'int | None'):
12091209
from . import _mem

amaranth/hdl/_mem.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def __init__(self, memory, *, domain="sync", transparent=True, src_loc_at=0):
262262
self.data = Signal(memory.width,
263263
name=f"{memory.name}_r_data", src_loc_at=1 + src_loc_at)
264264
if self.domain != "comb":
265-
self.en = Signal(name=f"{memory.name}_r_en", reset=1,
265+
self.en = Signal(name=f"{memory.name}_r_en", init=1,
266266
src_loc_at=1 + src_loc_at)
267267
else:
268268
self.en = Const(1)

amaranth/hdl/_xfrm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ def _insert_resets(self, fragment):
521521
domain = fragment.domains[domain_name]
522522
if domain.rst is None:
523523
continue
524-
stmts = [signal.eq(Const(signal.reset, signal.width))
524+
stmts = [signal.eq(Const(signal.init, signal.width))
525525
for signal in signals if not signal.reset_less]
526526
fragment.add_statements(domain_name, Switch(domain.rst, {1: stmts}))
527527

@@ -559,7 +559,7 @@ def __call__(self, value, *, src_loc_at=0):
559559

560560
class ResetInserter(_ControlInserter):
561561
def _insert_control(self, fragment, domain, signals):
562-
stmts = [s.eq(Const(s.reset, s.width)) for s in signals if not s.reset_less]
562+
stmts = [s.eq(Const(s.init, s.width)) for s in signals if not s.reset_less]
563563
fragment.add_statements(domain, Switch(self.controls[domain], {1: stmts}, src_loc=self.src_loc))
564564

565565

amaranth/lib/cdc.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import warnings
2+
13
from .. import *
24

35

@@ -26,8 +28,8 @@ class FFSynchronizer(Elaboratable):
2628
Signal connected to synchroniser output.
2729
o_domain : str
2830
Name of output clock domain.
29-
reset : int
30-
Reset value of the flip-flops. On FPGAs, even if ``reset_less`` is ``True``,
31+
init : int
32+
Initial and reset value of the flip-flops. On FPGAs, even if ``reset_less`` is ``True``,
3133
the :class:`FFSynchronizer` is still set to this value during initialization.
3234
reset_less : bool
3335
If ``True`` (the default), this :class:`FFSynchronizer` is unaffected by ``o_domain``
@@ -62,14 +64,24 @@ class FFSynchronizer(Elaboratable):
6264
Define the ``get_ff_sync`` platform method to override the implementation of
6365
:class:`FFSynchronizer`, e.g. to instantiate library cells directly.
6466
"""
65-
def __init__(self, i, o, *, o_domain="sync", reset=0, reset_less=True, stages=2,
67+
def __init__(self, i, o, *, o_domain="sync", init=None, reset=None, reset_less=True, stages=2,
6668
max_input_delay=None):
6769
_check_stages(stages)
6870

6971
self.i = i
7072
self.o = o
7173

72-
self._reset = reset
74+
# TODO(amaranth-0.7): remove
75+
if reset is not None:
76+
if init is not None:
77+
raise ValueError("Cannot specify both `reset` and `init`")
78+
warnings.warn("`reset=` is deprecated, use `init=` instead",
79+
DeprecationWarning, stacklevel=2)
80+
init = reset
81+
if init is None:
82+
init = 0
83+
84+
self._init = init
7385
self._reset_less = reset_less
7486
self._o_domain = o_domain
7587
self._stages = stages
@@ -87,7 +99,7 @@ def elaborate(self, platform):
8799

88100
m = Module()
89101
flops = [Signal(self.i.shape(), name=f"stage{index}",
90-
reset=self._reset, reset_less=self._reset_less)
102+
init=self._init, reset_less=self._reset_less)
91103
for index in range(self._stages)]
92104
for i, o in zip((self.i, *flops), flops):
93105
m.d[self._o_domain] += o.eq(i)
@@ -161,7 +173,7 @@ def elaborate(self, platform):
161173

162174
m = Module()
163175
m.domains += ClockDomain("async_ff", async_reset=True, local=True)
164-
flops = [Signal(1, name=f"stage{index}", reset=1)
176+
flops = [Signal(1, name=f"stage{index}", init=1)
165177
for index in range(self._stages)]
166178
for i, o in zip((0, *flops), flops):
167179
m.d.async_ff += o.eq(i)

amaranth/lib/crc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ def __init__(self, parameters):
383383
def elaborate(self, platform):
384384
m = Module()
385385

386-
crc_reg = Signal(self._crc_width, reset=self._initial_crc.value)
386+
crc_reg = Signal(self._crc_width, init=self._initial_crc.value)
387387
data_in = Signal(self._data_width)
388388

389389
# Optionally bit-reflect input words.

0 commit comments

Comments
 (0)