1 # nmigen: UnusedElaboratable=no
6 from ..cores
.pll
.lattice_ecp5
import PLL_LatticeECP5
9 class PLL_LatticeECP5__ParametersTestCase(unittest
.TestCase
):
10 def test_simple(self
):
11 params1
= PLL_LatticeECP5
.Parameters(
17 self
.assertEqual(params1
.i_domain
, "foo")
18 self
.assertEqual(params1
.i_freq
, 100e6
)
19 self
.assertEqual(params1
.i_reset_less
, True)
20 self
.assertEqual(params1
.o_domain
, "bar")
21 self
.assertEqual(params1
.o_freq
, 50e6
)
22 self
.assertEqual(params1
.fb_internal
, False)
24 params2
= PLL_LatticeECP5
.Parameters(
32 self
.assertEqual(params2
.i_domain
, "baz")
33 self
.assertEqual(params2
.i_freq
, 12e6
)
34 self
.assertEqual(params2
.i_reset_less
, False)
35 self
.assertEqual(params2
.o_domain
, "qux")
36 self
.assertEqual(params2
.o_freq
, 48e6
)
37 self
.assertEqual(params2
.fb_internal
, True)
39 def test_wrong_i_domain(self
):
40 with self
.assertRaisesRegex(TypeError,
41 r
"Input domain must be a string, not 1"):
42 params
= PLL_LatticeECP5
.Parameters(
49 def test_wrong_i_freq_type(self
):
50 with self
.assertRaisesRegex(TypeError,
51 r
"Input frequency must be an integer or a float, not 'baz'"):
52 params
= PLL_LatticeECP5
.Parameters(
59 def test_wrong_i_freq_range(self
):
60 with self
.assertRaisesRegex(ValueError,
61 r
"Input frequency must be between 8 and 400 MHz, not 420.0 MHz"):
62 params
= PLL_LatticeECP5
.Parameters(
69 def test_wrong_o_domain(self
):
70 with self
.assertRaisesRegex(TypeError,
71 r
"Output domain must be a string, not 1"):
72 params
= PLL_LatticeECP5
.Parameters(
79 def test_wrong_o_freq_type(self
):
80 with self
.assertRaisesRegex(TypeError,
81 r
"Output frequency must be an integer or a float, not 'baz'"):
82 params
= PLL_LatticeECP5
.Parameters(
89 def test_wrong_o_freq_range(self
):
90 with self
.assertRaisesRegex(ValueError,
91 r
"Output frequency must be between 10 and 400 MHz, not 420.0 MHz"):
92 params
= PLL_LatticeECP5
.Parameters(
99 def test_add_secondary_output_wrong_domain(self
):
100 params
= PLL_LatticeECP5
.Parameters(
106 with self
.assertRaisesRegex(TypeError,
107 r
"Output domain must be a string, not 1"):
108 params
.add_secondary_output(domain
=1, freq
=10e6
)
110 def test_add_secondary_output_wrong_freq_type(self
):
111 params
= PLL_LatticeECP5
.Parameters(
117 with self
.assertRaisesRegex(TypeError,
118 r
"Output frequency must be an integer or a float, not 'a'"):
119 params
.add_secondary_output(domain
="baz", freq
="a")
121 def test_add_secondary_output_wrong_freq_range(self
):
122 params
= PLL_LatticeECP5
.Parameters(
128 with self
.assertRaisesRegex(ValueError,
129 r
"Output frequency must be between 10 and 400 MHz, not 8.0 MHz"):
130 params
.add_secondary_output(domain
="baz", freq
=8e6
)
132 def test_add_secondary_output_wrong_phase_type(self
):
133 params
= PLL_LatticeECP5
.Parameters(
139 with self
.assertRaisesRegex(TypeError,
140 r
"Output phase must be an integer or a float, not 'a'"):
141 params
.add_secondary_output(domain
="baz", freq
=10e6
, phase
="a")
143 def test_add_secondary_output_wrong_phase_range(self
):
144 params
= PLL_LatticeECP5
.Parameters(
150 with self
.assertRaisesRegex(ValueError,
151 r
"Output phase must be between 0 and 360 degrees, not -1"):
152 params
.add_secondary_output(domain
="baz", freq
=10e6
, phase
=-1)
154 def test_add_secondary_output_exceeded(self
):
155 params
= PLL_LatticeECP5
.Parameters(
161 params
.add_secondary_output(domain
="a", freq
=10e6
)
162 params
.add_secondary_output(domain
="b", freq
=10e6
)
163 params
.add_secondary_output(domain
="c", freq
=10e6
)
164 with self
.assertRaisesRegex(ValueError,
165 r
"This PLL can drive at most 3 secondary outputs"):
166 params
.add_secondary_output(domain
="d", freq
=10e6
)
168 def test_add_secondary_output_same_domain(self
):
169 params
= PLL_LatticeECP5
.Parameters(
175 params
.add_secondary_output(domain
="a", freq
=10e6
)
176 with self
.assertRaisesRegex(ValueError,
177 r
"Output domain 'a' has already been added"):
178 params
.add_secondary_output(domain
="a", freq
=10e6
)
180 def test_compute_primary(self
):
181 def result(i_freq
, o_freq
):
182 params
= PLL_LatticeECP5
.Parameters(
189 return (params
.i_div
, params
.fb_div
, params
.op
.div
)
192 # Values are taken from ecppll in prjtrellis.
193 # i_freq, o_freq, i_div, fb_div, op_div
194 ( 12e6
, 48e6
, 1, 4, 12),
195 ( 12e6
, 60e6
, 1, 5, 10),
196 ( 20e6
, 30e6
, 2, 3, 20),
197 ( 45e6
, 30e6
, 3, 2, 20),
198 ( 100e6
, 400e6
, 1, 4, 1),
199 ( 200e6
, 400e6
, 1, 2, 1),
200 ( 50e6
, 400e6
, 1, 8, 1),
201 ( 70e6
, 40e6
, 7, 4, 15),
202 ( 12e6
, 36e6
, 1, 3, 17),
203 ( 12e6
, 96e6
, 1, 8, 6),
204 ( 90e6
, 40e6
, 9, 4, 15),
205 ( 90e6
, 50e6
, 9, 5, 12),
206 ( 43e6
, 86e6
, 1, 2, 7),
210 [(i_freq
, o_freq
, *result(i_freq
, o_freq
)) for i_freq
, o_freq
, *_
in vectors
],
215 # def test_compute_secondary(self):
218 def test_add_secondary_output_frozen(self
):
219 params
= PLL_LatticeECP5
.Parameters(
226 with self
.assertRaisesRegex(ValueError,
227 r
"PLL parameters have already been computed. Other outputs cannot be added"):
228 params
.add_secondary_output(domain
="a", freq
=10e6
)