Skip to content

Commit 750cbbc

Browse files
committed
hdl: remove deprecated Sample, Past, Stable, Rose, Fell.
1 parent 475b0f3 commit 750cbbc

File tree

13 files changed

+23
-328
lines changed

13 files changed

+23
-328
lines changed

Diff for: amaranth/asserts.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
from .hdl.ast import AnyConst, AnySeq, Assert, Assume, Cover
2-
from .hdl.ast import Past, Stable, Rose, Fell, Initial
1+
from .hdl.ast import AnyConst, AnySeq, Initial, Assert, Assume, Cover
2+
3+
4+
__all__ = ["AnyConst", "AnySeq", "Initial", "Assert", "Assume", "Cover"]

Diff for: amaranth/back/rtlil.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -398,12 +398,6 @@ def on_ClockSignal(self, value):
398398
def on_ResetSignal(self, value):
399399
raise NotImplementedError # :nocov:
400400

401-
def on_Sample(self, value):
402-
raise NotImplementedError # :nocov:
403-
404-
def on_Initial(self, value):
405-
raise NotImplementedError # :nocov:
406-
407401
def on_Cat(self, value):
408402
return "{{ {} }}".format(" ".join(reversed([self(o) for o in value.parts])))
409403

@@ -498,6 +492,13 @@ def on_AnySeq(self, value):
498492
self.s.anys[value] = res
499493
return res
500494

495+
def on_Initial(self, value):
496+
res = self.s.rtlil.wire(width=1, src=_src(value.src_loc))
497+
self.s.rtlil.cell("$initstate", ports={
498+
"\\Y": res,
499+
}, src=_src(value.src_loc))
500+
return res
501+
501502
def on_Signal(self, value):
502503
wire_curr, wire_next = self.s.resolve(value)
503504
return wire_curr
@@ -646,6 +647,9 @@ def on_AnyConst(self, value):
646647
def on_AnySeq(self, value):
647648
raise TypeError # :nocov:
648649

650+
def on_Initial(self, value):
651+
raise TypeError # :nocov:
652+
649653
def on_Operator(self, value):
650654
if value.operator in ("u", "s"):
651655
# These operators are transparent on the LHS.

Diff for: amaranth/build/plat.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .. import __version__
1010
from .._toolchain import *
1111
from ..hdl import *
12-
from ..hdl.xfrm import SampleLowerer, DomainLowerer
12+
from ..hdl.xfrm import DomainLowerer
1313
from ..lib.cdc import ResetSynchronizer
1414
from ..back import rtlil, verilog
1515
from .res import *
@@ -143,7 +143,6 @@ def prepare(self, elaboratable, name="top", **kwargs):
143143
self._prepared = True
144144

145145
fragment = Fragment.get(elaboratable, self)
146-
fragment = SampleLowerer()(fragment)
147146
fragment._propagate_domains(self.create_missing_domain, platform=self)
148147
fragment = DomainLowerer()(fragment)
149148

Diff for: amaranth/hdl/ast.py

+2-72
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"Array", "ArrayProxy",
2121
"Signal", "ClockSignal", "ResetSignal",
2222
"ValueCastable", "ValueLike",
23-
"Sample", "Past", "Stable", "Rose", "Fell", "Initial",
23+
"Initial",
2424
"Statement", "Switch",
2525
"Property", "Assign", "Assert", "Assume", "Cover",
2626
"ValueKey", "ValueDict", "ValueSet", "SignalKey", "SignalDict", "SignalSet",
@@ -1549,70 +1549,6 @@ def __new__(cls, *args, **kwargs):
15491549
raise TypeError("ValueLike is an abstract class and cannot be constructed")
15501550

15511551

1552-
# TODO(amaranth-0.5): remove
1553-
@final
1554-
class Sample(Value):
1555-
"""Value from the past.
1556-
1557-
A ``Sample`` of an expression is equal to the value of the expression ``clocks`` clock edges
1558-
of the ``domain`` clock back. If that moment is before the beginning of time, it is equal
1559-
to the value of the expression calculated as if each signal had its reset value.
1560-
"""
1561-
@deprecated("instead of using `Sample`, create a register explicitly")
1562-
def __init__(self, expr, clocks, domain, *, src_loc_at=0):
1563-
super().__init__(src_loc_at=1 + src_loc_at)
1564-
self.value = Value.cast(expr)
1565-
self.clocks = int(clocks)
1566-
self.domain = domain
1567-
if not isinstance(self.value, (Const, Signal, ClockSignal, ResetSignal, Initial)):
1568-
raise TypeError("Sampled value must be a signal or a constant, not {!r}"
1569-
.format(self.value))
1570-
if self.clocks < 0:
1571-
raise ValueError("Cannot sample a value {} cycles in the future"
1572-
.format(-self.clocks))
1573-
if not (self.domain is None or isinstance(self.domain, str)):
1574-
raise TypeError("Domain name must be a string or None, not {!r}"
1575-
.format(self.domain))
1576-
1577-
def shape(self):
1578-
return self.value.shape()
1579-
1580-
def _rhs_signals(self):
1581-
return SignalSet((self,))
1582-
1583-
def __repr__(self):
1584-
return "(sample {!r} @ {}[{}])".format(
1585-
self.value, "<default>" if self.domain is None else self.domain, self.clocks)
1586-
1587-
1588-
# TODO(amaranth-0.5): remove
1589-
@deprecated("instead of using `Past`, create a register explicitly")
1590-
def Past(expr, clocks=1, domain=None):
1591-
with _ignore_deprecated():
1592-
return Sample(expr, clocks, domain)
1593-
1594-
1595-
# TODO(amaranth-0.5): remove
1596-
@deprecated("instead of using `Stable`, create registers and comparisons explicitly")
1597-
def Stable(expr, clocks=0, domain=None):
1598-
with _ignore_deprecated():
1599-
return Sample(expr, clocks + 1, domain) == Sample(expr, clocks, domain)
1600-
1601-
1602-
# TODO(amaranth-0.5): remove
1603-
@deprecated("instead of using `Rose`, create registers and comparisons explicitly")
1604-
def Rose(expr, clocks=0, domain=None):
1605-
with _ignore_deprecated():
1606-
return ~Sample(expr, clocks + 1, domain) & Sample(expr, clocks, domain)
1607-
1608-
1609-
# TODO(amaranth-0.5): remove
1610-
@deprecated("instead of using `Fell`, create registers and comparisons explicitly")
1611-
def Fell(expr, clocks=0, domain=None):
1612-
with _ignore_deprecated():
1613-
return Sample(expr, clocks + 1, domain) & ~Sample(expr, clocks, domain)
1614-
1615-
16161552
@final
16171553
class Initial(Value):
16181554
"""Start indicator, for model checking.
@@ -1626,7 +1562,7 @@ def shape(self):
16261562
return Shape(1)
16271563

16281564
def _rhs_signals(self):
1629-
return SignalSet((self,))
1565+
return SignalSet()
16301566

16311567
def __repr__(self):
16321568
return "(initial)"
@@ -1895,8 +1831,6 @@ def __init__(self, value):
18951831
elif isinstance(self.value, ArrayProxy):
18961832
self._hash = hash((ValueKey(self.value.index),
18971833
tuple(ValueKey(e) for e in self.value._iter_as_values())))
1898-
elif isinstance(self.value, Sample):
1899-
self._hash = hash((ValueKey(self.value.value), self.value.clocks, self.value.domain))
19001834
elif isinstance(self.value, Initial):
19011835
self._hash = 0
19021836
else: # :nocov:
@@ -1942,10 +1876,6 @@ def __eq__(self, other):
19421876
all(ValueKey(a) == ValueKey(b)
19431877
for a, b in zip(self.value._iter_as_values(),
19441878
other.value._iter_as_values())))
1945-
elif isinstance(self.value, Sample):
1946-
return (ValueKey(self.value.value) == ValueKey(other.value.value) and
1947-
self.value.clocks == other.value.clocks and
1948-
self.value.domain == self.value.domain)
19491879
elif isinstance(self.value, Initial):
19501880
return True
19511881
else: # :nocov:

Diff for: amaranth/hdl/dsl.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,6 @@ def domain_name(domain):
491491
.format(domain_name(domain)))
492492

493493
stmt._MustUse__used = True
494-
stmt = SampleDomainInjector(domain)(stmt)
495494

496495
for signal in stmt._lhs_signals():
497496
if signal not in self._driving:
@@ -539,8 +538,7 @@ def elaborate(self, platform):
539538
fragment.add_subfragment(Fragment.get(self._named_submodules[name], platform), name)
540539
for submodule in self._anon_submodules:
541540
fragment.add_subfragment(Fragment.get(submodule, platform), None)
542-
statements = SampleDomainInjector("sync")(self._statements)
543-
fragment.add_statements(statements)
541+
fragment.add_statements(self._statements)
544542
for signal, domain in self._driving.items():
545543
fragment.add_driver(signal, domain)
546544
fragment.add_domains(self._domains.values())

Diff for: amaranth/hdl/ir.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -506,11 +506,10 @@ def lca_of(fragu, fragv):
506506
self.add_ports(sig, dir="i")
507507

508508
def prepare(self, ports=None, missing_domain=lambda name: ClockDomain(name)):
509-
from .xfrm import SampleLowerer, DomainLowerer
509+
from .xfrm import DomainLowerer
510510

511-
fragment = SampleLowerer()(self)
512-
new_domains = fragment._propagate_domains(missing_domain)
513-
fragment = DomainLowerer()(fragment)
511+
new_domains = self._propagate_domains(missing_domain)
512+
fragment = DomainLowerer()(self)
514513
if ports is None:
515514
fragment._propagate_ports(ports=(), all_undef_as_ports=True)
516515
else:

Diff for: amaranth/hdl/xfrm.py

-88
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"FragmentTransformer",
1616
"TransformedElaboratable",
1717
"DomainCollector", "DomainRenamer", "DomainLowerer",
18-
"SampleDomainInjector", "SampleLowerer",
1918
"SwitchCleaner", "LHSGroupAnalyzer", "LHSGroupFilter",
2019
"ResetInserter", "EnableInserter"]
2120

@@ -65,10 +64,6 @@ def on_Cat(self, value):
6564
def on_ArrayProxy(self, value):
6665
pass # :nocov:
6766

68-
@abstractmethod
69-
def on_Sample(self, value):
70-
pass # :nocov:
71-
7267
@abstractmethod
7368
def on_Initial(self, value):
7469
pass # :nocov:
@@ -103,8 +98,6 @@ def on_value(self, value):
10398
new_value = self.on_Cat(value)
10499
elif type(value) is ArrayProxy:
105100
new_value = self.on_ArrayProxy(value)
106-
elif type(value) is Sample:
107-
new_value = self.on_Sample(value)
108101
elif type(value) is Initial:
109102
new_value = self.on_Initial(value)
110103
else:
@@ -153,9 +146,6 @@ def on_ArrayProxy(self, value):
153146
return ArrayProxy([self.on_value(elem) for elem in value._iter_as_values()],
154147
self.on_value(value.index))
155148

156-
def on_Sample(self, value):
157-
return Sample(self.on_value(value.value), value.clocks, value.domain)
158-
159149
def on_Initial(self, value):
160150
return value
161151

@@ -369,9 +359,6 @@ def on_ArrayProxy(self, value):
369359
self.on_value(elem)
370360
self.on_value(value.index)
371361

372-
def on_Sample(self, value):
373-
self.on_value(value.value)
374-
375362
def on_Initial(self, value):
376363
pass
377364

@@ -509,81 +496,6 @@ def on_fragment(self, fragment):
509496
return new_fragment
510497

511498

512-
class SampleDomainInjector(ValueTransformer, StatementTransformer):
513-
def __init__(self, domain):
514-
self.domain = domain
515-
516-
@_ignore_deprecated
517-
def on_Sample(self, value):
518-
if value.domain is not None:
519-
return value
520-
return Sample(value.value, value.clocks, self.domain)
521-
522-
def __call__(self, stmts):
523-
return self.on_statement(stmts)
524-
525-
526-
class SampleLowerer(FragmentTransformer, ValueTransformer, StatementTransformer):
527-
def __init__(self):
528-
self.initial = None
529-
self.sample_cache = None
530-
self.sample_stmts = None
531-
532-
def _name_reset(self, value):
533-
if isinstance(value, Const):
534-
return f"c${value.value}", value.value
535-
elif isinstance(value, Signal):
536-
return f"s${value.name}", value.reset
537-
elif isinstance(value, ClockSignal):
538-
return "clk", 0
539-
elif isinstance(value, ResetSignal):
540-
return "rst", 1
541-
elif isinstance(value, Initial):
542-
return "init", 0 # Past(Initial()) produces 0, 1, 0, 0, ...
543-
else:
544-
raise NotImplementedError # :nocov:
545-
546-
@_ignore_deprecated
547-
def on_Sample(self, value):
548-
if value in self.sample_cache:
549-
return self.sample_cache[value]
550-
551-
sampled_value = self.on_value(value.value)
552-
if value.clocks == 0:
553-
sample = sampled_value
554-
else:
555-
assert value.domain is not None
556-
sampled_name, sampled_reset = self._name_reset(value.value)
557-
name = f"$sample${sampled_name}${value.domain}${value.clocks}"
558-
sample = Signal.like(value.value, name=name, reset_less=True, reset=sampled_reset)
559-
sample.attrs["amaranth.sample_reg"] = True
560-
561-
prev_sample = self.on_Sample(Sample(sampled_value, value.clocks - 1, value.domain))
562-
if value.domain not in self.sample_stmts:
563-
self.sample_stmts[value.domain] = []
564-
self.sample_stmts[value.domain].append(sample.eq(prev_sample))
565-
566-
self.sample_cache[value] = sample
567-
return sample
568-
569-
def on_Initial(self, value):
570-
if self.initial is None:
571-
self.initial = Signal(name="init")
572-
return self.initial
573-
574-
def map_statements(self, fragment, new_fragment):
575-
self.initial = None
576-
self.sample_cache = ValueDict()
577-
self.sample_stmts = OrderedDict()
578-
new_fragment.add_statements(map(self.on_statement, fragment.statements))
579-
for domain, stmts in self.sample_stmts.items():
580-
new_fragment.add_statements(stmts)
581-
for stmt in stmts:
582-
new_fragment.add_driver(stmt.lhs, domain)
583-
if self.initial is not None:
584-
new_fragment.add_subfragment(Instance("$initstate", o_Y=self.initial))
585-
586-
587499
class SwitchCleaner(StatementVisitor):
588500
def on_ignore(self, stmt):
589501
return stmt

Diff for: amaranth/sim/_pyrtl.py

-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ def on_AnyConst(self, value):
103103
def on_AnySeq(self, value):
104104
raise NotImplementedError # :nocov:
105105

106-
def on_Sample(self, value):
107-
raise NotImplementedError # :nocov:
108-
109106
def on_Initial(self, value):
110107
raise NotImplementedError # :nocov:
111108

Diff for: docs/changes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Language changes
1313
.. currentmodule:: amaranth.hdl
1414

1515
* Removed: (deprecated in 0.4) :meth:`Const.normalize`. (`RFC 5`_)
16+
* Removed: (deprecated in 0.4) :class:`ast.Sample`, :class:`ast.Past`, :class:`ast.Stable`, :class:`ast.Rose`, :class:`ast.Fell`.
1617

1718

1819
Standard library changes

Diff for: tests/test_hdl_ast.py

+1-34
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ def test_repr(self):
894894
def test_cast(self):
895895
c = Cat(1, 0)
896896
self.assertEqual(repr(c), "(cat (const 1'd1) (const 1'd0))")
897-
897+
898898
def test_str_wrong(self):
899899
with self.assertRaisesRegex(TypeError,
900900
r"^Object 'foo' cannot be converted to an Amaranth value$"):
@@ -1382,39 +1382,6 @@ class EnumD(Enum):
13821382
self.assertFalse(isinstance(EnumD.A, ValueLike))
13831383

13841384

1385-
class SampleTestCase(FHDLTestCase):
1386-
@_ignore_deprecated
1387-
def test_const(self):
1388-
s = Sample(1, 1, "sync")
1389-
self.assertEqual(s.shape(), unsigned(1))
1390-
1391-
@_ignore_deprecated
1392-
def test_signal(self):
1393-
s1 = Sample(Signal(2), 1, "sync")
1394-
self.assertEqual(s1.shape(), unsigned(2))
1395-
s2 = Sample(ClockSignal(), 1, "sync")
1396-
s3 = Sample(ResetSignal(), 1, "sync")
1397-
1398-
@_ignore_deprecated
1399-
def test_wrong_value_operator(self):
1400-
with self.assertRaisesRegex(TypeError,
1401-
(r"^Sampled value must be a signal or a constant, not "
1402-
r"\(\+ \(sig \$signal\) \(const 1'd1\)\)$")):
1403-
Sample(Signal() + 1, 1, "sync")
1404-
1405-
@_ignore_deprecated
1406-
def test_wrong_clocks_neg(self):
1407-
with self.assertRaisesRegex(ValueError,
1408-
r"^Cannot sample a value 1 cycles in the future$"):
1409-
Sample(Signal(), -1, "sync")
1410-
1411-
@_ignore_deprecated
1412-
def test_wrong_domain(self):
1413-
with self.assertRaisesRegex(TypeError,
1414-
r"^Domain name must be a string or None, not 0$"):
1415-
Sample(Signal(), 1, 0)
1416-
1417-
14181385
class InitialTestCase(FHDLTestCase):
14191386
def test_initial(self):
14201387
i = Initial()

0 commit comments

Comments
 (0)