Commit 55859128 authored by Sebastien Bourdeauducq's avatar Sebastien Bourdeauducq
Browse files

cdc: avoid race between data and request in BusSynchronizer

parent f4979a24
......@@ -101,13 +101,17 @@ class BusSynchronizer(Module):
starter = Signal(reset=1)
sync_i += starter.eq(0)
self.submodules._ping = PulseSynchronizer(idomain, odomain)
# Extra flop on i->o to avoid race between data and request
# https://github.com/m-labs/nmigen/pull/40#issuecomment-484166790
ping_o = Signal()
sync_o += ping_o.eq(self._ping.o)
self.submodules._pong = PulseSynchronizer(odomain, idomain)
self.submodules._timeout = ClockDomainsRenamer(idomain)(
WaitTimer(timeout))
self.comb += [
self._timeout.wait.eq(~self._ping.i),
self._ping.i.eq(starter | self._pong.o | self._timeout.done),
self._pong.i.eq(self._ping.o)
self._pong.i.eq(ping_o)
]
ibuffer = Signal(width, reset_less=True)
......@@ -115,7 +119,7 @@ class BusSynchronizer(Module):
sync_i += If(self._pong.o, ibuffer.eq(self.i))
ibuffer.attr.add("no_retiming")
self.specials += MultiReg(ibuffer, obuffer, odomain)
sync_o += If(self._ping.o, self.o.eq(obuffer))
sync_o += If(ping_o, self.o.eq(obuffer))
class BlindTransfer(Module):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment