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>
5 from operator
import xor
, add
6 from functools
import reduce
9 from migen
.genlib
.cdc
import MultiReg
11 # PRBS Generators ----------------------------------------------------------------------------------
13 class PRBSGenerator(Module
):
14 def __init__(self
, n_out
, n_state
=23, taps
=[17, 22]):
15 self
.o
= Signal(n_out
)
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
])
28 state
.eq(Cat(*curval
[:n_state
])),
29 self
.o
.eq(Cat(*curval
))
33 class PRBS7Generator(PRBSGenerator
):
34 def __init__(self
, n_out
):
35 PRBSGenerator
.__init
__(self
, n_out
, n_state
=7, taps
=[5, 6])
38 class PRBS15Generator(PRBSGenerator
):
39 def __init__(self
, n_out
):
40 PRBSGenerator
.__init
__(self
, n_out
, n_state
=15, taps
=[13, 14])
43 class PRBS31Generator(PRBSGenerator
):
44 def __init__(self
, n_out
):
45 PRBSGenerator
.__init
__(self
, n_out
, n_state
=31, taps
=[27, 30])
47 # PRBS TX ------------------------------------------------------------------------------------------
50 def __init__(self
, width
, reverse
=False):
51 self
.config
= Signal(2)
52 self
.i
= Signal(width
)
53 self
.o
= Signal(width
)
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
67 prbs_data
= Signal(width
)
70 prbs_data
.eq(prbs31
.o
)
71 ).Elif(config
== 0b10,
72 prbs_data
.eq(prbs15
.o
)
77 # optional bits reversing
79 new_prbs_data
= Signal(width
)
80 self
.comb
+= new_prbs_data
.eq(prbs_data
[::-1])
81 prbs_data
= new_prbs_data
91 # PRBS Checkers ------------------------------------------------------------------------------------
93 class PRBSChecker(Module
):
94 def __init__(self
, n_in
, n_state
=23, taps
=[17, 22]):
96 self
.errors
= Signal(n_in
)
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
])
108 self
.sync
+= state
.eq(Cat(*curval
[:n_state
]))
111 class PRBS7Checker(PRBSChecker
):
112 def __init__(self
, n_out
):
113 PRBSChecker
.__init
__(self
, n_out
, n_state
=7, taps
=[5, 6])
116 class PRBS15Checker(PRBSChecker
):
117 def __init__(self
, n_out
):
118 PRBSChecker
.__init
__(self
, n_out
, n_state
=15, taps
=[13, 14])
121 class PRBS31Checker(PRBSChecker
):
122 def __init__(self
, n_out
):
123 PRBSChecker
.__init
__(self
, n_out
, n_state
=31, taps
=[27, 30])
125 # PRBS RX ------------------------------------------------------------------------------------------
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)
137 # optional bits reversing
140 new_prbs_data
= Signal(width
)
141 self
.comb
+= new_prbs_data
.eq(prbs_data
[::-1])
142 prbs_data
= new_prbs_data
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
151 prbs7
.i
.eq(prbs_data
),
152 prbs15
.i
.eq(prbs_data
),
153 prbs31
.i
.eq(prbs_data
)
160 ).Elif(self
.errors
!= (2**32-1),
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))