migen/genlib/cdc: fix BusSynchronizer
ping/pong token can be lost when: - source clock domain starts before destination clock domain. - a clock domain stops. This fix add a timeout to detect such situation and create another token.
This commit is contained in:
parent
07efe9d7b1
commit
210ba91d58
|
@ -2,6 +2,7 @@ from migen.fhdl.std import *
|
||||||
from migen.fhdl.bitcontainer import value_bits_sign
|
from migen.fhdl.bitcontainer import value_bits_sign
|
||||||
from migen.fhdl.specials import Special
|
from migen.fhdl.specials import Special
|
||||||
from migen.fhdl.tools import list_signals
|
from migen.fhdl.tools import list_signals
|
||||||
|
from migen.genlib.misc import WaitTimer
|
||||||
|
|
||||||
|
|
||||||
class NoRetiming(Special):
|
class NoRetiming(Special):
|
||||||
|
@ -88,7 +89,7 @@ class BusSynchronizer(Module):
|
||||||
Ensures that all the bits form a single word that was present
|
Ensures that all the bits form a single word that was present
|
||||||
synchronously in the input clock domain (unlike direct use of
|
synchronously in the input clock domain (unlike direct use of
|
||||||
``MultiReg``)."""
|
``MultiReg``)."""
|
||||||
def __init__(self, width, idomain, odomain):
|
def __init__(self, width, idomain, odomain, timeout=128):
|
||||||
self.i = Signal(width)
|
self.i = Signal(width)
|
||||||
self.o = Signal(width)
|
self.o = Signal(width)
|
||||||
|
|
||||||
|
@ -102,8 +103,10 @@ class BusSynchronizer(Module):
|
||||||
sync_i += starter.eq(0)
|
sync_i += starter.eq(0)
|
||||||
self.submodules._ping = PulseSynchronizer(idomain, odomain)
|
self.submodules._ping = PulseSynchronizer(idomain, odomain)
|
||||||
self.submodules._pong = PulseSynchronizer(odomain, idomain)
|
self.submodules._pong = PulseSynchronizer(odomain, idomain)
|
||||||
|
self.submodules._timeout = WaitTimer(timeout)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self._ping.i.eq(starter | self._pong.o),
|
self._timeout.wait.eq(~self._ping.i),
|
||||||
|
self._ping.i.eq(starter | self._pong.o | self._timeout.done),
|
||||||
self._pong.i.eq(self._ping.i)
|
self._pong.i.eq(self._ping.i)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue