hdl: remove deprecated Sample
, Past
, Stable
, Rose
, Fell
.
This commit is contained in:
parent
475b0f35dd
commit
750cbbc3c7
|
@ -1,2 +1,4 @@
|
|||
from .hdl.ast import AnyConst, AnySeq, Assert, Assume, Cover
|
||||
from .hdl.ast import Past, Stable, Rose, Fell, Initial
|
||||
from .hdl.ast import AnyConst, AnySeq, Initial, Assert, Assume, Cover
|
||||
|
||||
|
||||
__all__ = ["AnyConst", "AnySeq", "Initial", "Assert", "Assume", "Cover"]
|
||||
|
|
|
@ -398,12 +398,6 @@ class _ValueCompiler(xfrm.ValueVisitor):
|
|||
def on_ResetSignal(self, value):
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
def on_Sample(self, value):
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
def on_Initial(self, value):
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
def on_Cat(self, value):
|
||||
return "{{ {} }}".format(" ".join(reversed([self(o) for o in value.parts])))
|
||||
|
||||
|
@ -498,6 +492,13 @@ class _RHSValueCompiler(_ValueCompiler):
|
|||
self.s.anys[value] = res
|
||||
return res
|
||||
|
||||
def on_Initial(self, value):
|
||||
res = self.s.rtlil.wire(width=1, src=_src(value.src_loc))
|
||||
self.s.rtlil.cell("$initstate", ports={
|
||||
"\\Y": res,
|
||||
}, src=_src(value.src_loc))
|
||||
return res
|
||||
|
||||
def on_Signal(self, value):
|
||||
wire_curr, wire_next = self.s.resolve(value)
|
||||
return wire_curr
|
||||
|
@ -646,6 +647,9 @@ class _LHSValueCompiler(_ValueCompiler):
|
|||
def on_AnySeq(self, value):
|
||||
raise TypeError # :nocov:
|
||||
|
||||
def on_Initial(self, value):
|
||||
raise TypeError # :nocov:
|
||||
|
||||
def on_Operator(self, value):
|
||||
if value.operator in ("u", "s"):
|
||||
# These operators are transparent on the LHS.
|
||||
|
|
|
@ -9,7 +9,7 @@ import jinja2
|
|||
from .. import __version__
|
||||
from .._toolchain import *
|
||||
from ..hdl import *
|
||||
from ..hdl.xfrm import SampleLowerer, DomainLowerer
|
||||
from ..hdl.xfrm import DomainLowerer
|
||||
from ..lib.cdc import ResetSynchronizer
|
||||
from ..back import rtlil, verilog
|
||||
from .res import *
|
||||
|
@ -143,7 +143,6 @@ class Platform(ResourceManager, metaclass=ABCMeta):
|
|||
self._prepared = True
|
||||
|
||||
fragment = Fragment.get(elaboratable, self)
|
||||
fragment = SampleLowerer()(fragment)
|
||||
fragment._propagate_domains(self.create_missing_domain, platform=self)
|
||||
fragment = DomainLowerer()(fragment)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ __all__ = [
|
|||
"Array", "ArrayProxy",
|
||||
"Signal", "ClockSignal", "ResetSignal",
|
||||
"ValueCastable", "ValueLike",
|
||||
"Sample", "Past", "Stable", "Rose", "Fell", "Initial",
|
||||
"Initial",
|
||||
"Statement", "Switch",
|
||||
"Property", "Assign", "Assert", "Assume", "Cover",
|
||||
"ValueKey", "ValueDict", "ValueSet", "SignalKey", "SignalDict", "SignalSet",
|
||||
|
@ -1549,70 +1549,6 @@ class ValueLike(metaclass=_ValueLikeMeta):
|
|||
raise TypeError("ValueLike is an abstract class and cannot be constructed")
|
||||
|
||||
|
||||
# TODO(amaranth-0.5): remove
|
||||
@final
|
||||
class Sample(Value):
|
||||
"""Value from the past.
|
||||
|
||||
A ``Sample`` of an expression is equal to the value of the expression ``clocks`` clock edges
|
||||
of the ``domain`` clock back. If that moment is before the beginning of time, it is equal
|
||||
to the value of the expression calculated as if each signal had its reset value.
|
||||
"""
|
||||
@deprecated("instead of using `Sample`, create a register explicitly")
|
||||
def __init__(self, expr, clocks, domain, *, src_loc_at=0):
|
||||
super().__init__(src_loc_at=1 + src_loc_at)
|
||||
self.value = Value.cast(expr)
|
||||
self.clocks = int(clocks)
|
||||
self.domain = domain
|
||||
if not isinstance(self.value, (Const, Signal, ClockSignal, ResetSignal, Initial)):
|
||||
raise TypeError("Sampled value must be a signal or a constant, not {!r}"
|
||||
.format(self.value))
|
||||
if self.clocks < 0:
|
||||
raise ValueError("Cannot sample a value {} cycles in the future"
|
||||
.format(-self.clocks))
|
||||
if not (self.domain is None or isinstance(self.domain, str)):
|
||||
raise TypeError("Domain name must be a string or None, not {!r}"
|
||||
.format(self.domain))
|
||||
|
||||
def shape(self):
|
||||
return self.value.shape()
|
||||
|
||||
def _rhs_signals(self):
|
||||
return SignalSet((self,))
|
||||
|
||||
def __repr__(self):
|
||||
return "(sample {!r} @ {}[{}])".format(
|
||||
self.value, "<default>" if self.domain is None else self.domain, self.clocks)
|
||||
|
||||
|
||||
# TODO(amaranth-0.5): remove
|
||||
@deprecated("instead of using `Past`, create a register explicitly")
|
||||
def Past(expr, clocks=1, domain=None):
|
||||
with _ignore_deprecated():
|
||||
return Sample(expr, clocks, domain)
|
||||
|
||||
|
||||
# TODO(amaranth-0.5): remove
|
||||
@deprecated("instead of using `Stable`, create registers and comparisons explicitly")
|
||||
def Stable(expr, clocks=0, domain=None):
|
||||
with _ignore_deprecated():
|
||||
return Sample(expr, clocks + 1, domain) == Sample(expr, clocks, domain)
|
||||
|
||||
|
||||
# TODO(amaranth-0.5): remove
|
||||
@deprecated("instead of using `Rose`, create registers and comparisons explicitly")
|
||||
def Rose(expr, clocks=0, domain=None):
|
||||
with _ignore_deprecated():
|
||||
return ~Sample(expr, clocks + 1, domain) & Sample(expr, clocks, domain)
|
||||
|
||||
|
||||
# TODO(amaranth-0.5): remove
|
||||
@deprecated("instead of using `Fell`, create registers and comparisons explicitly")
|
||||
def Fell(expr, clocks=0, domain=None):
|
||||
with _ignore_deprecated():
|
||||
return Sample(expr, clocks + 1, domain) & ~Sample(expr, clocks, domain)
|
||||
|
||||
|
||||
@final
|
||||
class Initial(Value):
|
||||
"""Start indicator, for model checking.
|
||||
|
@ -1626,7 +1562,7 @@ class Initial(Value):
|
|||
return Shape(1)
|
||||
|
||||
def _rhs_signals(self):
|
||||
return SignalSet((self,))
|
||||
return SignalSet()
|
||||
|
||||
def __repr__(self):
|
||||
return "(initial)"
|
||||
|
@ -1895,8 +1831,6 @@ class ValueKey:
|
|||
elif isinstance(self.value, ArrayProxy):
|
||||
self._hash = hash((ValueKey(self.value.index),
|
||||
tuple(ValueKey(e) for e in self.value._iter_as_values())))
|
||||
elif isinstance(self.value, Sample):
|
||||
self._hash = hash((ValueKey(self.value.value), self.value.clocks, self.value.domain))
|
||||
elif isinstance(self.value, Initial):
|
||||
self._hash = 0
|
||||
else: # :nocov:
|
||||
|
@ -1942,10 +1876,6 @@ class ValueKey:
|
|||
all(ValueKey(a) == ValueKey(b)
|
||||
for a, b in zip(self.value._iter_as_values(),
|
||||
other.value._iter_as_values())))
|
||||
elif isinstance(self.value, Sample):
|
||||
return (ValueKey(self.value.value) == ValueKey(other.value.value) and
|
||||
self.value.clocks == other.value.clocks and
|
||||
self.value.domain == self.value.domain)
|
||||
elif isinstance(self.value, Initial):
|
||||
return True
|
||||
else: # :nocov:
|
||||
|
|
|
@ -491,7 +491,6 @@ class Module(_ModuleBuilderRoot, Elaboratable):
|
|||
.format(domain_name(domain)))
|
||||
|
||||
stmt._MustUse__used = True
|
||||
stmt = SampleDomainInjector(domain)(stmt)
|
||||
|
||||
for signal in stmt._lhs_signals():
|
||||
if signal not in self._driving:
|
||||
|
@ -539,8 +538,7 @@ class Module(_ModuleBuilderRoot, Elaboratable):
|
|||
fragment.add_subfragment(Fragment.get(self._named_submodules[name], platform), name)
|
||||
for submodule in self._anon_submodules:
|
||||
fragment.add_subfragment(Fragment.get(submodule, platform), None)
|
||||
statements = SampleDomainInjector("sync")(self._statements)
|
||||
fragment.add_statements(statements)
|
||||
fragment.add_statements(self._statements)
|
||||
for signal, domain in self._driving.items():
|
||||
fragment.add_driver(signal, domain)
|
||||
fragment.add_domains(self._domains.values())
|
||||
|
|
|
@ -506,11 +506,10 @@ class Fragment:
|
|||
self.add_ports(sig, dir="i")
|
||||
|
||||
def prepare(self, ports=None, missing_domain=lambda name: ClockDomain(name)):
|
||||
from .xfrm import SampleLowerer, DomainLowerer
|
||||
from .xfrm import DomainLowerer
|
||||
|
||||
fragment = SampleLowerer()(self)
|
||||
new_domains = fragment._propagate_domains(missing_domain)
|
||||
fragment = DomainLowerer()(fragment)
|
||||
new_domains = self._propagate_domains(missing_domain)
|
||||
fragment = DomainLowerer()(self)
|
||||
if ports is None:
|
||||
fragment._propagate_ports(ports=(), all_undef_as_ports=True)
|
||||
else:
|
||||
|
|
|
@ -15,7 +15,6 @@ __all__ = ["ValueVisitor", "ValueTransformer",
|
|||
"FragmentTransformer",
|
||||
"TransformedElaboratable",
|
||||
"DomainCollector", "DomainRenamer", "DomainLowerer",
|
||||
"SampleDomainInjector", "SampleLowerer",
|
||||
"SwitchCleaner", "LHSGroupAnalyzer", "LHSGroupFilter",
|
||||
"ResetInserter", "EnableInserter"]
|
||||
|
||||
|
@ -65,10 +64,6 @@ class ValueVisitor(metaclass=ABCMeta):
|
|||
def on_ArrayProxy(self, value):
|
||||
pass # :nocov:
|
||||
|
||||
@abstractmethod
|
||||
def on_Sample(self, value):
|
||||
pass # :nocov:
|
||||
|
||||
@abstractmethod
|
||||
def on_Initial(self, value):
|
||||
pass # :nocov:
|
||||
|
@ -103,8 +98,6 @@ class ValueVisitor(metaclass=ABCMeta):
|
|||
new_value = self.on_Cat(value)
|
||||
elif type(value) is ArrayProxy:
|
||||
new_value = self.on_ArrayProxy(value)
|
||||
elif type(value) is Sample:
|
||||
new_value = self.on_Sample(value)
|
||||
elif type(value) is Initial:
|
||||
new_value = self.on_Initial(value)
|
||||
else:
|
||||
|
@ -153,9 +146,6 @@ class ValueTransformer(ValueVisitor):
|
|||
return ArrayProxy([self.on_value(elem) for elem in value._iter_as_values()],
|
||||
self.on_value(value.index))
|
||||
|
||||
def on_Sample(self, value):
|
||||
return Sample(self.on_value(value.value), value.clocks, value.domain)
|
||||
|
||||
def on_Initial(self, value):
|
||||
return value
|
||||
|
||||
|
@ -369,9 +359,6 @@ class DomainCollector(ValueVisitor, StatementVisitor):
|
|||
self.on_value(elem)
|
||||
self.on_value(value.index)
|
||||
|
||||
def on_Sample(self, value):
|
||||
self.on_value(value.value)
|
||||
|
||||
def on_Initial(self, value):
|
||||
pass
|
||||
|
||||
|
@ -509,81 +496,6 @@ class DomainLowerer(FragmentTransformer, ValueTransformer, StatementTransformer)
|
|||
return new_fragment
|
||||
|
||||
|
||||
class SampleDomainInjector(ValueTransformer, StatementTransformer):
|
||||
def __init__(self, domain):
|
||||
self.domain = domain
|
||||
|
||||
@_ignore_deprecated
|
||||
def on_Sample(self, value):
|
||||
if value.domain is not None:
|
||||
return value
|
||||
return Sample(value.value, value.clocks, self.domain)
|
||||
|
||||
def __call__(self, stmts):
|
||||
return self.on_statement(stmts)
|
||||
|
||||
|
||||
class SampleLowerer(FragmentTransformer, ValueTransformer, StatementTransformer):
|
||||
def __init__(self):
|
||||
self.initial = None
|
||||
self.sample_cache = None
|
||||
self.sample_stmts = None
|
||||
|
||||
def _name_reset(self, value):
|
||||
if isinstance(value, Const):
|
||||
return f"c${value.value}", value.value
|
||||
elif isinstance(value, Signal):
|
||||
return f"s${value.name}", value.reset
|
||||
elif isinstance(value, ClockSignal):
|
||||
return "clk", 0
|
||||
elif isinstance(value, ResetSignal):
|
||||
return "rst", 1
|
||||
elif isinstance(value, Initial):
|
||||
return "init", 0 # Past(Initial()) produces 0, 1, 0, 0, ...
|
||||
else:
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
@_ignore_deprecated
|
||||
def on_Sample(self, value):
|
||||
if value in self.sample_cache:
|
||||
return self.sample_cache[value]
|
||||
|
||||
sampled_value = self.on_value(value.value)
|
||||
if value.clocks == 0:
|
||||
sample = sampled_value
|
||||
else:
|
||||
assert value.domain is not None
|
||||
sampled_name, sampled_reset = self._name_reset(value.value)
|
||||
name = f"$sample${sampled_name}${value.domain}${value.clocks}"
|
||||
sample = Signal.like(value.value, name=name, reset_less=True, reset=sampled_reset)
|
||||
sample.attrs["amaranth.sample_reg"] = True
|
||||
|
||||
prev_sample = self.on_Sample(Sample(sampled_value, value.clocks - 1, value.domain))
|
||||
if value.domain not in self.sample_stmts:
|
||||
self.sample_stmts[value.domain] = []
|
||||
self.sample_stmts[value.domain].append(sample.eq(prev_sample))
|
||||
|
||||
self.sample_cache[value] = sample
|
||||
return sample
|
||||
|
||||
def on_Initial(self, value):
|
||||
if self.initial is None:
|
||||
self.initial = Signal(name="init")
|
||||
return self.initial
|
||||
|
||||
def map_statements(self, fragment, new_fragment):
|
||||
self.initial = None
|
||||
self.sample_cache = ValueDict()
|
||||
self.sample_stmts = OrderedDict()
|
||||
new_fragment.add_statements(map(self.on_statement, fragment.statements))
|
||||
for domain, stmts in self.sample_stmts.items():
|
||||
new_fragment.add_statements(stmts)
|
||||
for stmt in stmts:
|
||||
new_fragment.add_driver(stmt.lhs, domain)
|
||||
if self.initial is not None:
|
||||
new_fragment.add_subfragment(Instance("$initstate", o_Y=self.initial))
|
||||
|
||||
|
||||
class SwitchCleaner(StatementVisitor):
|
||||
def on_ignore(self, stmt):
|
||||
return stmt
|
||||
|
|
|
@ -103,9 +103,6 @@ class _ValueCompiler(ValueVisitor, _Compiler):
|
|||
def on_AnySeq(self, value):
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
def on_Sample(self, value):
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
def on_Initial(self, value):
|
||||
raise NotImplementedError # :nocov:
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ Language changes
|
|||
.. currentmodule:: amaranth.hdl
|
||||
|
||||
* Removed: (deprecated in 0.4) :meth:`Const.normalize`. (`RFC 5`_)
|
||||
* Removed: (deprecated in 0.4) :class:`ast.Sample`, :class:`ast.Past`, :class:`ast.Stable`, :class:`ast.Rose`, :class:`ast.Fell`.
|
||||
|
||||
|
||||
Standard library changes
|
||||
|
|
|
@ -894,7 +894,7 @@ class CatTestCase(FHDLTestCase):
|
|||
def test_cast(self):
|
||||
c = Cat(1, 0)
|
||||
self.assertEqual(repr(c), "(cat (const 1'd1) (const 1'd0))")
|
||||
|
||||
|
||||
def test_str_wrong(self):
|
||||
with self.assertRaisesRegex(TypeError,
|
||||
r"^Object 'foo' cannot be converted to an Amaranth value$"):
|
||||
|
@ -1382,39 +1382,6 @@ class ValueLikeTestCase(FHDLTestCase):
|
|||
self.assertFalse(isinstance(EnumD.A, ValueLike))
|
||||
|
||||
|
||||
class SampleTestCase(FHDLTestCase):
|
||||
@_ignore_deprecated
|
||||
def test_const(self):
|
||||
s = Sample(1, 1, "sync")
|
||||
self.assertEqual(s.shape(), unsigned(1))
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_signal(self):
|
||||
s1 = Sample(Signal(2), 1, "sync")
|
||||
self.assertEqual(s1.shape(), unsigned(2))
|
||||
s2 = Sample(ClockSignal(), 1, "sync")
|
||||
s3 = Sample(ResetSignal(), 1, "sync")
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_wrong_value_operator(self):
|
||||
with self.assertRaisesRegex(TypeError,
|
||||
(r"^Sampled value must be a signal or a constant, not "
|
||||
r"\(\+ \(sig \$signal\) \(const 1'd1\)\)$")):
|
||||
Sample(Signal() + 1, 1, "sync")
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_wrong_clocks_neg(self):
|
||||
with self.assertRaisesRegex(ValueError,
|
||||
r"^Cannot sample a value 1 cycles in the future$"):
|
||||
Sample(Signal(), -1, "sync")
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_wrong_domain(self):
|
||||
with self.assertRaisesRegex(TypeError,
|
||||
r"^Domain name must be a string or None, not 0$"):
|
||||
Sample(Signal(), 1, 0)
|
||||
|
||||
|
||||
class InitialTestCase(FHDLTestCase):
|
||||
def test_initial(self):
|
||||
i = Initial()
|
||||
|
|
|
@ -133,25 +133,6 @@ class DSLTestCase(FHDLTestCase):
|
|||
)
|
||||
""")
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_sample_domain(self):
|
||||
m = Module()
|
||||
i = Signal()
|
||||
o1 = Signal()
|
||||
o2 = Signal()
|
||||
o3 = Signal()
|
||||
m.d.sync += o1.eq(Past(i))
|
||||
m.d.pix += o2.eq(Past(i))
|
||||
m.d.pix += o3.eq(Past(i, domain="sync"))
|
||||
f = m.elaborate(platform=None)
|
||||
self.assertRepr(f.statements, """
|
||||
(
|
||||
(eq (sig o1) (sample (sig i) @ sync[1]))
|
||||
(eq (sig o2) (sample (sig i) @ pix[1]))
|
||||
(eq (sig o3) (sample (sig i) @ sync[1]))
|
||||
)
|
||||
""")
|
||||
|
||||
def test_If(self):
|
||||
m = Module()
|
||||
with m.If(self.s1):
|
||||
|
|
|
@ -210,54 +210,6 @@ class DomainLowererTestCase(FHDLTestCase):
|
|||
DomainLowerer()(f)
|
||||
|
||||
|
||||
class SampleLowererTestCase(FHDLTestCase):
|
||||
def setUp(self):
|
||||
self.i = Signal()
|
||||
self.o1 = Signal()
|
||||
self.o2 = Signal()
|
||||
self.o3 = Signal()
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_lower_signal(self):
|
||||
f = Fragment()
|
||||
f.add_statements(
|
||||
self.o1.eq(Sample(self.i, 2, "sync")),
|
||||
self.o2.eq(Sample(self.i, 1, "sync")),
|
||||
self.o3.eq(Sample(self.i, 1, "pix")),
|
||||
)
|
||||
|
||||
f = SampleLowerer()(f)
|
||||
self.assertRepr(f.statements, """
|
||||
(
|
||||
(eq (sig o1) (sig $sample$s$i$sync$2))
|
||||
(eq (sig o2) (sig $sample$s$i$sync$1))
|
||||
(eq (sig o3) (sig $sample$s$i$pix$1))
|
||||
(eq (sig $sample$s$i$sync$1) (sig i))
|
||||
(eq (sig $sample$s$i$sync$2) (sig $sample$s$i$sync$1))
|
||||
(eq (sig $sample$s$i$pix$1) (sig i))
|
||||
)
|
||||
""")
|
||||
self.assertEqual(len(f.drivers["sync"]), 2)
|
||||
self.assertEqual(len(f.drivers["pix"]), 1)
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_lower_const(self):
|
||||
f = Fragment()
|
||||
f.add_statements(
|
||||
self.o1.eq(Sample(1, 2, "sync")),
|
||||
)
|
||||
|
||||
f = SampleLowerer()(f)
|
||||
self.assertRepr(f.statements, """
|
||||
(
|
||||
(eq (sig o1) (sig $sample$c$1$sync$2))
|
||||
(eq (sig $sample$c$1$sync$1) (const 1'd1))
|
||||
(eq (sig $sample$c$1$sync$2) (sig $sample$c$1$sync$1))
|
||||
)
|
||||
""")
|
||||
self.assertEqual(len(f.drivers["sync"]), 2)
|
||||
|
||||
|
||||
class SwitchCleanerTestCase(FHDLTestCase):
|
||||
def test_clean(self):
|
||||
a = Signal()
|
||||
|
|
|
@ -911,53 +911,6 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
|
|||
sim.add_clock(1e-6)
|
||||
sim.add_sync_process(process)
|
||||
|
||||
@_ignore_deprecated
|
||||
def test_sample_helpers(self):
|
||||
m = Module()
|
||||
s = Signal(2)
|
||||
def mk(x):
|
||||
y = Signal.like(x)
|
||||
m.d.comb += y.eq(x)
|
||||
return y
|
||||
p0, r0, f0, s0 = mk(Past(s, 0)), mk(Rose(s)), mk(Fell(s)), mk(Stable(s))
|
||||
p1, r1, f1, s1 = mk(Past(s)), mk(Rose(s, 1)), mk(Fell(s, 1)), mk(Stable(s, 1))
|
||||
p2, r2, f2, s2 = mk(Past(s, 2)), mk(Rose(s, 2)), mk(Fell(s, 2)), mk(Stable(s, 2))
|
||||
p3, r3, f3, s3 = mk(Past(s, 3)), mk(Rose(s, 3)), mk(Fell(s, 3)), mk(Stable(s, 3))
|
||||
with self.assertSimulation(m) as sim:
|
||||
def process_gen():
|
||||
yield s.eq(0b10)
|
||||
yield
|
||||
yield
|
||||
yield s.eq(0b01)
|
||||
yield
|
||||
def process_check():
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
|
||||
self.assertEqual((yield p0), 0b01)
|
||||
self.assertEqual((yield p1), 0b10)
|
||||
self.assertEqual((yield p2), 0b10)
|
||||
self.assertEqual((yield p3), 0b00)
|
||||
|
||||
self.assertEqual((yield s0), 0b0)
|
||||
self.assertEqual((yield s1), 0b1)
|
||||
self.assertEqual((yield s2), 0b0)
|
||||
self.assertEqual((yield s3), 0b1)
|
||||
|
||||
self.assertEqual((yield r0), 0b01)
|
||||
self.assertEqual((yield r1), 0b00)
|
||||
self.assertEqual((yield r2), 0b10)
|
||||
self.assertEqual((yield r3), 0b00)
|
||||
|
||||
self.assertEqual((yield f0), 0b10)
|
||||
self.assertEqual((yield f1), 0b00)
|
||||
self.assertEqual((yield f2), 0b00)
|
||||
self.assertEqual((yield f3), 0b00)
|
||||
sim.add_clock(1e-6)
|
||||
sim.add_sync_process(process_gen)
|
||||
sim.add_sync_process(process_check)
|
||||
|
||||
def test_vcd_wrong_nonzero_time(self):
|
||||
s = Signal()
|
||||
m = Module()
|
||||
|
|
Loading…
Reference in a new issue