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