hdl.mem: use read_port(domain="comb") for asynchronous read ports.
[nmigen.git] / nmigen / test / test_lib_coding.py
1 from .tools import *
2 from ..hdl import *
3 from ..formal import *
4 from ..back.pysim import *
5 from ..lib.coding import *
6
7
8 class EncoderTestCase(FHDLTestCase):
9 def test_basic(self):
10 enc = Encoder(4)
11 with Simulator(enc) as sim:
12 def process():
13 self.assertEqual((yield enc.n), 1)
14 self.assertEqual((yield enc.o), 0)
15
16 yield enc.i.eq(0b0001)
17 yield Delay()
18 self.assertEqual((yield enc.n), 0)
19 self.assertEqual((yield enc.o), 0)
20
21 yield enc.i.eq(0b0100)
22 yield Delay()
23 self.assertEqual((yield enc.n), 0)
24 self.assertEqual((yield enc.o), 2)
25
26 yield enc.i.eq(0b0110)
27 yield Delay()
28 self.assertEqual((yield enc.n), 1)
29 self.assertEqual((yield enc.o), 0)
30
31 sim.add_process(process)
32 sim.run()
33
34
35 class PriorityEncoderTestCase(FHDLTestCase):
36 def test_basic(self):
37 enc = PriorityEncoder(4)
38 with Simulator(enc) as sim:
39 def process():
40 self.assertEqual((yield enc.n), 1)
41 self.assertEqual((yield enc.o), 0)
42
43 yield enc.i.eq(0b0001)
44 yield Delay()
45 self.assertEqual((yield enc.n), 0)
46 self.assertEqual((yield enc.o), 0)
47
48 yield enc.i.eq(0b0100)
49 yield Delay()
50 self.assertEqual((yield enc.n), 0)
51 self.assertEqual((yield enc.o), 2)
52
53 yield enc.i.eq(0b0110)
54 yield Delay()
55 self.assertEqual((yield enc.n), 0)
56 self.assertEqual((yield enc.o), 1)
57
58 sim.add_process(process)
59 sim.run()
60
61
62 class DecoderTestCase(FHDLTestCase):
63 def test_basic(self):
64 dec = Decoder(4)
65 with Simulator(dec) as sim:
66 def process():
67 self.assertEqual((yield dec.o), 0b0001)
68
69 yield dec.i.eq(1)
70 yield Delay()
71 self.assertEqual((yield dec.o), 0b0010)
72
73 yield dec.i.eq(3)
74 yield Delay()
75 self.assertEqual((yield dec.o), 0b1000)
76
77 yield dec.n.eq(1)
78 yield Delay()
79 self.assertEqual((yield dec.o), 0b0000)
80
81 sim.add_process(process)
82 sim.run()
83
84
85 class ReversibleSpec(Elaboratable):
86 def __init__(self, encoder_cls, decoder_cls, args):
87 self.encoder_cls = encoder_cls
88 self.decoder_cls = decoder_cls
89 self.coder_args = args
90
91 def elaborate(self, platform):
92 m = Module()
93 enc, dec = self.encoder_cls(*self.coder_args), self.decoder_cls(*self.coder_args)
94 m.submodules += enc, dec
95 m.d.comb += [
96 dec.i.eq(enc.o),
97 Assert(enc.i == dec.o)
98 ]
99 return m
100
101
102 class HammingDistanceSpec(Elaboratable):
103 def __init__(self, distance, encoder_cls, args):
104 self.distance = distance
105 self.encoder_cls = encoder_cls
106 self.coder_args = args
107
108 def elaborate(self, platform):
109 m = Module()
110 enc1, enc2 = self.encoder_cls(*self.coder_args), self.encoder_cls(*self.coder_args)
111 m.submodules += enc1, enc2
112 m.d.comb += [
113 Assume(enc1.i + 1 == enc2.i),
114 Assert(sum(enc1.o ^ enc2.o) == self.distance)
115 ]
116 return m
117
118
119 class GrayCoderTestCase(FHDLTestCase):
120 def test_reversible(self):
121 spec = ReversibleSpec(encoder_cls=GrayEncoder, decoder_cls=GrayDecoder, args=(16,))
122 self.assertFormal(spec, mode="prove")
123
124 def test_distance(self):
125 spec = HammingDistanceSpec(distance=1, encoder_cls=GrayEncoder, args=(16,))
126 self.assertFormal(spec, mode="prove")