diff --git a/test/test_prbs.py b/test/test_prbs.py new file mode 100644 index 000000000..953cff354 --- /dev/null +++ b/test/test_prbs.py @@ -0,0 +1,103 @@ +import unittest + +from migen import * + +from litex.soc.cores.prbs import * + + +class PRBSModel: + def __init__(self, n_state=23, taps=[17, 22]): + self.n_state = n_state + self.taps = taps + self.state = 1 + + def getbit(self): + feedback = 0 + for tap in self.taps: + feedback = feedback ^ (self.state >> tap) & 0x1 + self.state = (self.state << 1) & (2**self.n_state-1) | feedback + return feedback + + def getbits(self, n): + v = 0 + for i in range(n): + v <<= 1 + v |= self.getbit() + return v + + +class PRBS7Model(PRBSModel): + def __init__(self): + PRBSModel.__init__(self, n_state=7, taps=[5, 6]) + + +class PRBS15Model(PRBSModel): + def __init__(self): + PRBSModel.__init__(self, n_state=15, taps=[13, 14]) + + +class PRBS31Model(PRBSModel): + def __init__(self): + PRBSModel.__init__(self, n_state=31, taps=[27, 30]) + + +class TestPRBS(unittest.TestCase): + def test_prbs_generator(self): + duts = { + "prbs7": PRBS7Generator(8), + "prbs15": PRBS15Generator(16), + "prbs31": PRBS31Generator(32), + } + models = { + "prbs7": PRBS7Model(), + "prbs15": PRBS15Model(), + "prbs31": PRBS31Model(), + } + errors = 0 + for test in ["prbs7", "prbs15", "prbs31"]: + dut = duts[test] + dut._errors = 0 + model = models[test] + def checker(dut, cycles): + yield + # Let the generator run and check values against model. + for i in range(cycles): + if (yield dut.o) != model.getbits(len(dut.o)): + dut._errors += 1 + yield + run_simulation(dut, checker(dut, 1024)) + self.assertEqual(dut._errors, 0) + + def test_prbs_checker(self): + duts = { + "prbs7": PRBS7Checker(8), + "prbs15": PRBS15Checker(16), + "prbs31": PRBS31Checker(32), + } + models = { + "prbs7": PRBS7Model(), + "prbs15": PRBS15Model(), + "prbs31": PRBS31Model(), + } + errors = 0 + for test in ["prbs7", "prbs15", "prbs31"]: + dut = duts[test] + dut._errors = 0 + model = models[test] + @passive + def generator(dut): + # Inject PRBS values from model. + while True: + yield dut.i.eq(model.getbits(len(dut.i))) + yield + def checker(dut, cycles): + # Wait PRBS synchronization. + for i in range(8): + yield + # Check that no errors are reported. + for i in range(cycles): + if (yield dut.errors) != 0: + dut._errors += 1 + yield + run_simulation(dut, [generator(dut), checker(dut, 1024)]) + self.assertEqual(dut._errors, 0)