lib.cdc: add diagnostic checks for synchronization stage count.
This commit is contained in:
parent
52e761dc33
commit
22da78ca28
|
@ -7,6 +7,14 @@ __all__ = ["FFSynchronizer", "ResetSynchronizer"]
|
||||||
__all__ += ["MultiReg"]
|
__all__ += ["MultiReg"]
|
||||||
|
|
||||||
|
|
||||||
|
def _check_stages(stages):
|
||||||
|
if not isinstance(stages, int) or stages < 1:
|
||||||
|
raise TypeError("Synchronization stage count must be a positive integer, not '{!r}'"
|
||||||
|
.format(stages))
|
||||||
|
if stages < 2:
|
||||||
|
raise ValueError("Synchronization stage count may not safely be less than 2")
|
||||||
|
|
||||||
|
|
||||||
class FFSynchronizer(Elaboratable):
|
class FFSynchronizer(Elaboratable):
|
||||||
"""Resynchronise a signal to a different clock domain.
|
"""Resynchronise a signal to a different clock domain.
|
||||||
|
|
||||||
|
@ -53,7 +61,9 @@ class FFSynchronizer(Elaboratable):
|
||||||
|
|
||||||
:class:`FFSynchronizer` is reset by the ``o_domain`` reset only.
|
:class:`FFSynchronizer` is reset by the ``o_domain`` reset only.
|
||||||
"""
|
"""
|
||||||
def __init__(self, i, o, *, o_domain="sync", stages=2, reset=0, reset_less=True):
|
def __init__(self, i, o, *, o_domain="sync", reset=0, reset_less=True, stages=2):
|
||||||
|
_check_stages(stages)
|
||||||
|
|
||||||
self.i = i
|
self.i = i
|
||||||
self.o = o
|
self.o = o
|
||||||
|
|
||||||
|
@ -108,6 +118,8 @@ class ResetSynchronizer(Elaboratable):
|
||||||
:class:`ResetSynchronizer`, e.g. to instantiate library cells directly.
|
:class:`ResetSynchronizer`, e.g. to instantiate library cells directly.
|
||||||
"""
|
"""
|
||||||
def __init__(self, arst, *, domain="sync", stages=2):
|
def __init__(self, arst, *, domain="sync", stages=2):
|
||||||
|
_check_stages(stages)
|
||||||
|
|
||||||
self.arst = arst
|
self.arst = arst
|
||||||
|
|
||||||
self._domain = domain
|
self._domain = domain
|
||||||
|
|
|
@ -5,6 +5,14 @@ from ..lib.cdc import *
|
||||||
|
|
||||||
|
|
||||||
class FFSynchronizerTestCase(FHDLTestCase):
|
class FFSynchronizerTestCase(FHDLTestCase):
|
||||||
|
def test_stages_wrong(self):
|
||||||
|
with self.assertRaises(TypeError,
|
||||||
|
msg="Synchronization stage count must be a positive integer, not '0'"):
|
||||||
|
FFSynchronizer(Signal(), Signal(), stages=0)
|
||||||
|
with self.assertRaises(ValueError,
|
||||||
|
msg="Synchronization stage count may not safely be less than 2"):
|
||||||
|
FFSynchronizer(Signal(), Signal(), stages=1)
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
i = Signal()
|
i = Signal()
|
||||||
o = Signal()
|
o = Signal()
|
||||||
|
@ -43,6 +51,14 @@ class FFSynchronizerTestCase(FHDLTestCase):
|
||||||
|
|
||||||
|
|
||||||
class ResetSynchronizerTestCase(FHDLTestCase):
|
class ResetSynchronizerTestCase(FHDLTestCase):
|
||||||
|
def test_stages_wrong(self):
|
||||||
|
with self.assertRaises(TypeError,
|
||||||
|
msg="Synchronization stage count must be a positive integer, not '0'"):
|
||||||
|
ResetSynchronizer(Signal(), stages=0)
|
||||||
|
with self.assertRaises(ValueError,
|
||||||
|
msg="Synchronization stage count may not safely be less than 2"):
|
||||||
|
ResetSynchronizer(Signal(), stages=1)
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
arst = Signal()
|
arst = Signal()
|
||||||
m = Module()
|
m = Module()
|
||||||
|
|
Loading…
Reference in a new issue