soc/integration/csr_bridge: use registered version only when SDRAM is present.
[litex.git] / test / test_ecc.py
1 # This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
2 # License: BSD
3
4 import unittest
5 import random
6
7 from migen import *
8
9 from litedram.common import *
10 from litedram.frontend.ecc import *
11
12 from litex.gen.sim import *
13
14
15 class TestECC(unittest.TestCase):
16 def test_m_n(self):
17 m, n = compute_m_n(15)
18 self.assertEqual(m, 5)
19 self.assertEqual(n, 20)
20
21 def test_syndrome_positions(self):
22 p_pos = compute_syndrome_positions(20)
23 p_pos_ref = [1, 2, 4, 8, 16]
24 self.assertEqual(p_pos, p_pos_ref)
25
26 def test_data_positions(self):
27 d_pos = compute_data_positions(20)
28 d_pos_ref = [3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20]
29 self.assertEqual(d_pos, d_pos_ref)
30
31 def test_cover_positions(self):
32 c_pos_ref = {
33 0 : [1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
34 1 : [2, 3, 6, 7, 10, 11, 14, 15, 18, 19],
35 2 : [4, 5, 6, 7, 12, 13, 14, 15, 20],
36 3 : [8, 9, 10, 11, 12, 13, 14, 15],
37 4 : [16, 17, 18, 19, 20]
38 }
39 for i in range(5):
40 c_pos = compute_cover_positions(20, 2**i)
41 self.assertEqual(c_pos, c_pos_ref[i])
42
43 def test_ecc(self, k=15):
44 class DUT(Module):
45 def __init__(self, k):
46 m, n = compute_m_n(k)
47 self.flip = Signal(n + 1)
48
49 # # #
50
51 self.submodules.encoder = ECCEncoder(k)
52 self.submodules.decoder = ECCDecoder(k)
53
54 self.comb += self.decoder.i.eq(self.encoder.o ^ self.flip)
55
56 def generator(dut, k, nvalues, nerrors):
57 dut.errors = 0
58 prng = random.Random(42)
59 yield dut.decoder.enable.eq(1)
60 for i in range(nvalues):
61 data = prng.randrange(2**k-1)
62 yield dut.encoder.i.eq(data)
63 # FIXME: error when fliping parity bit
64 if nerrors == 1:
65 flip_bit1 = (prng.randrange(len(dut.flip)-2) + 1)
66 yield dut.flip.eq(1<<flip_bit1)
67 elif nerrors == 2:
68 flip_bit1 = (prng.randrange(len(dut.flip)-2) + 1)
69 flip_bit2 = flip_bit1
70 while flip_bit2 == flip_bit1:
71 flip_bit2 = (prng.randrange(len(dut.flip)-2) + 1)
72 yield dut.flip.eq((1<<flip_bit1) | (1<<flip_bit2))
73 yield
74 # if less than 2 errors, check data
75 if nerrors < 2:
76 if (yield dut.decoder.o) != data:
77 dut.errors += 1
78 # if 0 error, verify sec == 0 / ded == 0
79 if nerrors == 0:
80 if (yield dut.decoder.sec) != 0:
81 dut.errors += 1
82 if (yield dut.decoder.ded) != 0:
83 dut.errors += 1
84 # if 1 error, verify sec == 1 / dec == 0
85 elif nerrors == 1:
86 if (yield dut.decoder.sec) != 1:
87 dut.errors += 1
88 if (yield dut.decoder.ded) != 0:
89 dut.errors += 1
90 # if 2 errors, verify sec == 0 / ded == 1
91 elif nerrors == 2:
92 if (yield dut.decoder.sec) != 0:
93 dut.errors += 1
94 if (yield dut.decoder.ded) != 1:
95 dut.errors += 1
96
97 for i in range(3):
98 dut = DUT(k)
99 run_simulation(dut, generator(dut, k, 128, i))
100 self.assertEqual(dut.errors, 0)