cores/dma: add stream.last support on WishboneDMAReader.
[litex.git] / litex / soc / cores / prbs.py
1 # This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
2 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
3 # License: BSD
4
5 from operator import xor, add
6 from functools import reduce
7
8 from migen import *
9 from migen.genlib.cdc import MultiReg
10
11 # PRBS Generators ----------------------------------------------------------------------------------
12
13 class PRBSGenerator(Module):
14 def __init__(self, n_out, n_state=23, taps=[17, 22]):
15 self.o = Signal(n_out)
16
17 # # #
18
19 state = Signal(n_state, reset=1)
20 curval = [state[i] for i in range(n_state)]
21 curval += [0]*(n_out - n_state)
22 for i in range(n_out):
23 nv = reduce(xor, [curval[tap] for tap in taps])
24 curval.insert(0, nv)
25 curval.pop()
26
27 self.sync += [
28 state.eq(Cat(*curval[:n_state])),
29 self.o.eq(Cat(*curval))
30 ]
31
32
33 class PRBS7Generator(PRBSGenerator):
34 def __init__(self, n_out):
35 PRBSGenerator.__init__(self, n_out, n_state=7, taps=[5, 6])
36
37
38 class PRBS15Generator(PRBSGenerator):
39 def __init__(self, n_out):
40 PRBSGenerator.__init__(self, n_out, n_state=15, taps=[13, 14])
41
42
43 class PRBS31Generator(PRBSGenerator):
44 def __init__(self, n_out):
45 PRBSGenerator.__init__(self, n_out, n_state=31, taps=[27, 30])
46
47 # PRBS TX ------------------------------------------------------------------------------------------
48
49 class PRBSTX(Module):
50 def __init__(self, width, reverse=False):
51 self.config = Signal(2)
52 self.i = Signal(width)
53 self.o = Signal(width)
54
55 # # #
56
57 config = Signal(2)
58
59 # generators
60 self.specials += MultiReg(self.config, config)
61 prbs7 = PRBS7Generator(width)
62 prbs15 = PRBS15Generator(width)
63 prbs31 = PRBS31Generator(width)
64 self.submodules += prbs7, prbs15, prbs31
65
66 # select
67 prbs_data = Signal(width)
68 self.comb += \
69 If(config == 0b11,
70 prbs_data.eq(prbs31.o)
71 ).Elif(config == 0b10,
72 prbs_data.eq(prbs15.o)
73 ).Else(
74 prbs_data.eq(prbs7.o)
75 )
76
77 # optional bits reversing
78 if reverse:
79 new_prbs_data = Signal(width)
80 self.comb += new_prbs_data.eq(prbs_data[::-1])
81 prbs_data = new_prbs_data
82
83 # prbs / data mux
84 self.comb += \
85 If(config == 0,
86 self.o.eq(self.i)
87 ).Else(
88 self.o.eq(prbs_data)
89 )
90
91 # PRBS Checkers ------------------------------------------------------------------------------------
92
93 class PRBSChecker(Module):
94 def __init__(self, n_in, n_state=23, taps=[17, 22]):
95 self.i = Signal(n_in)
96 self.errors = Signal(n_in)
97
98 # # #
99
100 state = Signal(n_state, reset=1)
101 curval = [state[i] for i in range(n_state)]
102 for i in reversed(range(n_in)):
103 correctv = reduce(xor, [curval[tap] for tap in taps])
104 self.sync += self.errors[i].eq(self.i[i] != correctv)
105 curval.insert(0, self.i[i])
106 curval.pop()
107
108 self.sync += state.eq(Cat(*curval[:n_state]))
109
110
111 class PRBS7Checker(PRBSChecker):
112 def __init__(self, n_out):
113 PRBSChecker.__init__(self, n_out, n_state=7, taps=[5, 6])
114
115
116 class PRBS15Checker(PRBSChecker):
117 def __init__(self, n_out):
118 PRBSChecker.__init__(self, n_out, n_state=15, taps=[13, 14])
119
120
121 class PRBS31Checker(PRBSChecker):
122 def __init__(self, n_out):
123 PRBSChecker.__init__(self, n_out, n_state=31, taps=[27, 30])
124
125 # PRBS RX ------------------------------------------------------------------------------------------
126
127 class PRBSRX(Module):
128 def __init__(self, width, reverse=False):
129 self.i = Signal(width)
130 self.config = Signal(2)
131 self.errors = Signal(32)
132
133 # # #
134
135 config = Signal(2)
136
137 # optional bits reversing
138 prbs_data = self.i
139 if reverse:
140 new_prbs_data = Signal(width)
141 self.comb += new_prbs_data.eq(prbs_data[::-1])
142 prbs_data = new_prbs_data
143
144 # checkers
145 self.specials += MultiReg(self.config, config)
146 prbs7 = PRBS7Checker(width)
147 prbs15 = PRBS15Checker(width)
148 prbs31 = PRBS31Checker(width)
149 self.submodules += prbs7, prbs15, prbs31
150 self.comb += [
151 prbs7.i.eq(prbs_data),
152 prbs15.i.eq(prbs_data),
153 prbs31.i.eq(prbs_data)
154 ]
155
156 # errors count
157 self.sync += \
158 If(config == 0,
159 self.errors.eq(0)
160 ).Elif(self.errors != (2**32-1),
161 If(config == 0b01,
162 self.errors.eq(self.errors + (prbs7.errors != 0))
163 ).Elif(config == 0b10,
164 self.errors.eq(self.errors + (prbs15.errors != 0))
165 ).Elif(config == 0b11,
166 self.errors.eq(self.errors + (prbs31.errors != 0))
167 )
168 )