1 # nmigen: UnusedElaboratable=no
5 from ..back
.pysim
import *
6 from ..lib
.cdc
import *
9 class FFSynchronizerTestCase(FHDLTestCase
):
10 def test_stages_wrong(self
):
11 with self
.assertRaisesRegex(TypeError,
12 r
"^Synchronization stage count must be a positive integer, not 0$"):
13 FFSynchronizer(Signal(), Signal(), stages
=0)
14 with self
.assertRaisesRegex(ValueError,
15 r
"^Synchronization stage count may not safely be less than 2$"):
16 FFSynchronizer(Signal(), Signal(), stages
=1)
21 frag
= FFSynchronizer(i
, o
)
26 self
.assertEqual((yield o
), 0)
29 self
.assertEqual((yield o
), 0)
31 self
.assertEqual((yield o
), 0)
33 self
.assertEqual((yield o
), 1)
34 sim
.add_process(process
)
37 def test_reset_value(self
):
40 frag
= FFSynchronizer(i
, o
, reset
=1)
45 self
.assertEqual((yield o
), 1)
48 self
.assertEqual((yield o
), 1)
50 self
.assertEqual((yield o
), 1)
52 self
.assertEqual((yield o
), 0)
53 sim
.add_process(process
)
57 class AsyncFFSynchronizerTestCase(FHDLTestCase
):
58 def test_stages_wrong(self
):
59 with self
.assertRaisesRegex(TypeError,
60 r
"^Synchronization stage count must be a positive integer, not 0$"):
61 ResetSynchronizer(Signal(), stages
=0)
62 with self
.assertRaisesRegex(ValueError,
63 r
"^Synchronization stage count may not safely be less than 2$"):
64 ResetSynchronizer(Signal(), stages
=1)
66 def test_edge_wrong(self
):
67 with self
.assertRaisesRegex(ValueError,
68 r
"^AsyncFFSynchronizer async edge must be one of 'pos' or 'neg', not 'xxx'$"):
69 AsyncFFSynchronizer(Signal(), Signal(), o_domain
="sync", async_edge
="xxx")
71 def test_pos_edge(self
):
75 m
.domains
+= ClockDomain("sync")
76 m
.submodules
+= AsyncFFSynchronizer(i
, o
)
82 self
.assertEqual((yield i
), 0)
83 self
.assertEqual((yield o
), 1)
84 yield Tick(); yield Delay(1e-8)
85 self
.assertEqual((yield o
), 1)
86 yield Tick(); yield Delay(1e-8)
87 self
.assertEqual((yield o
), 0)
88 yield Tick(); yield Delay(1e-8)
89 self
.assertEqual((yield o
), 0)
90 yield Tick(); yield Delay(1e-8)
94 self
.assertEqual((yield o
), 1)
95 yield Tick(); yield Delay(1e-8)
96 self
.assertEqual((yield o
), 1)
98 yield Tick(); yield Delay(1e-8)
99 self
.assertEqual((yield o
), 1)
100 yield Tick(); yield Delay(1e-8)
101 self
.assertEqual((yield o
), 0)
102 yield Tick(); yield Delay(1e-8)
103 self
.assertEqual((yield o
), 0)
104 yield Tick(); yield Delay(1e-8)
105 sim
.add_process(process
)
106 with sim
.write_vcd("test.vcd"):
109 def test_neg_edge(self
):
113 m
.domains
+= ClockDomain("sync")
114 m
.submodules
+= AsyncFFSynchronizer(i
, o
, async_edge
="neg")
120 self
.assertEqual((yield i
), 1)
121 self
.assertEqual((yield o
), 1)
122 yield Tick(); yield Delay(1e-8)
123 self
.assertEqual((yield o
), 1)
124 yield Tick(); yield Delay(1e-8)
125 self
.assertEqual((yield o
), 0)
126 yield Tick(); yield Delay(1e-8)
127 self
.assertEqual((yield o
), 0)
128 yield Tick(); yield Delay(1e-8)
132 self
.assertEqual((yield o
), 1)
133 yield Tick(); yield Delay(1e-8)
134 self
.assertEqual((yield o
), 1)
136 yield Tick(); yield Delay(1e-8)
137 self
.assertEqual((yield o
), 1)
138 yield Tick(); yield Delay(1e-8)
139 self
.assertEqual((yield o
), 0)
140 yield Tick(); yield Delay(1e-8)
141 self
.assertEqual((yield o
), 0)
142 yield Tick(); yield Delay(1e-8)
143 sim
.add_process(process
)
144 with sim
.write_vcd("test.vcd"):
148 class ResetSynchronizerTestCase(FHDLTestCase
):
149 def test_stages_wrong(self
):
150 with self
.assertRaisesRegex(TypeError,
151 r
"^Synchronization stage count must be a positive integer, not 0$"):
152 ResetSynchronizer(Signal(), stages
=0)
153 with self
.assertRaisesRegex(ValueError,
154 r
"^Synchronization stage count may not safely be less than 2$"):
155 ResetSynchronizer(Signal(), stages
=1)
157 def test_basic(self
):
160 m
.domains
+= ClockDomain("sync")
161 m
.submodules
+= ResetSynchronizer(arst
)
169 self
.assertEqual((yield s
), 1)
170 yield Tick(); yield Delay(1e-8)
171 self
.assertEqual((yield s
), 1)
172 yield Tick(); yield Delay(1e-8)
173 self
.assertEqual((yield s
), 1)
174 yield Tick(); yield Delay(1e-8)
175 self
.assertEqual((yield s
), 0)
176 yield Tick(); yield Delay(1e-8)
180 self
.assertEqual((yield s
), 0)
181 yield Tick(); yield Delay(1e-8)
182 self
.assertEqual((yield s
), 1)
184 yield Tick(); yield Delay(1e-8)
185 self
.assertEqual((yield s
), 1)
186 yield Tick(); yield Delay(1e-8)
187 self
.assertEqual((yield s
), 1)
188 yield Tick(); yield Delay(1e-8)
189 self
.assertEqual((yield s
), 0)
190 yield Tick(); yield Delay(1e-8)
191 sim
.add_process(process
)
192 with sim
.write_vcd("test.vcd"):
196 # TODO: test with distinct clocks
197 class PulseSynchronizerTestCase(FHDLTestCase
):
198 def test_stages_wrong(self
):
199 with self
.assertRaisesRegex(TypeError,
200 r
"^Synchronization stage count must be a positive integer, not 0$"):
201 PulseSynchronizer("w", "r", stages
=0)
202 with self
.assertRaisesRegex(ValueError,
203 r
"^Synchronization stage count may not safely be less than 2$"):
204 PulseSynchronizer("w", "r", stages
=1)
206 def test_smoke(self
):
208 m
.domains
+= ClockDomain("sync")
209 ps
= m
.submodules
.dut
= PulseSynchronizer("sync", "sync")
215 # TODO: think about reset
218 # Make sure no pulses are generated in quiescent state
221 self
.assertEqual((yield ps
.o
), 0)
222 # Check conservation of pulses
225 yield ps
.i
.eq(1 if n
< 4 else 0)
228 self
.assertEqual(accum
, 4)
229 sim
.add_process(process
)