amaranth/nmigen/test/test_lib_coding.py
whitequark 7df70059d1 back.pysim: redesign the simulator.
The redesign introduces no fundamental incompatibilities, but it does
involve minor breaking changes:
  * The simulator commands were moved from hdl.ast to back.pysim
    (instead of only being reexported from back.pysim).
  * back.pysim.DeadlineError was removed.

Summary of changes:
  * The new simulator compiles HDL to Python code and is >6x faster.
    (The old one compiled HDL to lots of Python lambdas.)
  * The new simulator is a straightforward, rigorous implementation
    of the Synchronous Reactive Programming paradigm, instead of
    a pile of ad-hoc code with no particular design driving it.
  * The new simulator never raises DeadlineError, and there is no
    limit on the amount of delta cycles.
  * The new simulator robustly handles multiclock designs.
  * The new simulator can be reset, such that the compiled design
    can be reused, which can save significant runtime with large
    designs.
  * Generators can no longer be added as processes, since that would
    break reset(); only generator functions may be. If necessary,
    they may be added by wrapping them into a generator function;
    a deprecated fallback does just that. This workaround will raise
    an exception if the simulator is reset and restarted.
  * The new simulator does not depend on Python extensions.
    (The old one required bitarray, which did not provide wheels.)

Fixes #28.
Fixes #34.
Fixes #160.
Fixes #161.
Fixes #215.
Fixes #242.
Fixes #262.
2019-11-28 21:05:34 +00:00

127 lines
3.5 KiB
Python

from .utils import *
from ..hdl import *
from ..asserts import *
from ..back.pysim import *
from ..lib.coding import *
class EncoderTestCase(FHDLTestCase):
def test_basic(self):
enc = Encoder(4)
def process():
self.assertEqual((yield enc.n), 1)
self.assertEqual((yield enc.o), 0)
yield enc.i.eq(0b0001)
yield Settle()
self.assertEqual((yield enc.n), 0)
self.assertEqual((yield enc.o), 0)
yield enc.i.eq(0b0100)
yield Settle()
self.assertEqual((yield enc.n), 0)
self.assertEqual((yield enc.o), 2)
yield enc.i.eq(0b0110)
yield Settle()
self.assertEqual((yield enc.n), 1)
self.assertEqual((yield enc.o), 0)
sim = Simulator(enc)
sim.add_process(process)
sim.run()
class PriorityEncoderTestCase(FHDLTestCase):
def test_basic(self):
enc = PriorityEncoder(4)
def process():
self.assertEqual((yield enc.n), 1)
self.assertEqual((yield enc.o), 0)
yield enc.i.eq(0b0001)
yield Settle()
self.assertEqual((yield enc.n), 0)
self.assertEqual((yield enc.o), 0)
yield enc.i.eq(0b0100)
yield Settle()
self.assertEqual((yield enc.n), 0)
self.assertEqual((yield enc.o), 2)
yield enc.i.eq(0b0110)
yield Settle()
self.assertEqual((yield enc.n), 0)
self.assertEqual((yield enc.o), 1)
sim = Simulator(enc)
sim.add_process(process)
sim.run()
class DecoderTestCase(FHDLTestCase):
def test_basic(self):
dec = Decoder(4)
def process():
self.assertEqual((yield dec.o), 0b0001)
yield dec.i.eq(1)
yield Settle()
self.assertEqual((yield dec.o), 0b0010)
yield dec.i.eq(3)
yield Settle()
self.assertEqual((yield dec.o), 0b1000)
yield dec.n.eq(1)
yield Settle()
self.assertEqual((yield dec.o), 0b0000)
sim = Simulator(dec)
sim.add_process(process)
sim.run()
class ReversibleSpec(Elaboratable):
def __init__(self, encoder_cls, decoder_cls, args):
self.encoder_cls = encoder_cls
self.decoder_cls = decoder_cls
self.coder_args = args
def elaborate(self, platform):
m = Module()
enc, dec = self.encoder_cls(*self.coder_args), self.decoder_cls(*self.coder_args)
m.submodules += enc, dec
m.d.comb += [
dec.i.eq(enc.o),
Assert(enc.i == dec.o)
]
return m
class HammingDistanceSpec(Elaboratable):
def __init__(self, distance, encoder_cls, args):
self.distance = distance
self.encoder_cls = encoder_cls
self.coder_args = args
def elaborate(self, platform):
m = Module()
enc1, enc2 = self.encoder_cls(*self.coder_args), self.encoder_cls(*self.coder_args)
m.submodules += enc1, enc2
m.d.comb += [
Assume(enc1.i + 1 == enc2.i),
Assert(sum(enc1.o ^ enc2.o) == self.distance)
]
return m
class GrayCoderTestCase(FHDLTestCase):
def test_reversible(self):
spec = ReversibleSpec(encoder_cls=GrayEncoder, decoder_cls=GrayDecoder, args=(16,))
self.assertFormal(spec, mode="prove")
def test_distance(self):
spec = HammingDistanceSpec(distance=1, encoder_cls=GrayEncoder, args=(16,))
self.assertFormal(spec, mode="prove")