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): ...@@ -101,13 +101,17 @@ class BusSynchronizer(Module):
starter = Signal(reset=1) starter = Signal(reset=1)
sync_i += starter.eq(0) sync_i += starter.eq(0)
self.submodules._ping = PulseSynchronizer(idomain, odomain) 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._pong = PulseSynchronizer(odomain, idomain)
self.submodules._timeout = ClockDomainsRenamer(idomain)( self.submodules._timeout = ClockDomainsRenamer(idomain)(
WaitTimer(timeout)) WaitTimer(timeout))
self.comb += [ self.comb += [
self._timeout.wait.eq(~self._ping.i), self._timeout.wait.eq(~self._ping.i),
self._ping.i.eq(starter | self._pong.o | self._timeout.done), 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) ibuffer = Signal(width, reset_less=True)
...@@ -115,7 +119,7 @@ class BusSynchronizer(Module): ...@@ -115,7 +119,7 @@ class BusSynchronizer(Module):
sync_i += If(self._pong.o, ibuffer.eq(self.i)) sync_i += If(self._pong.o, ibuffer.eq(self.i))
ibuffer.attr.add("no_retiming") ibuffer.attr.add("no_retiming")
self.specials += MultiReg(ibuffer, obuffer, odomain) 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): 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