Skip to content

Commit fd16b66

Browse files
committedJun 2, 2015
genlib/cdc: add BusSynchronizer
1 parent 57102ec commit fd16b66

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed
 

‎migen/genlib/cdc.py

+32
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,38 @@ def __init__(self, idomain, odomain):
8282
self.comb += self.o.eq(toggle_o ^ toggle_o_r)
8383

8484

85+
class BusSynchronizer(Module):
86+
"""Clock domain transfer of several bits at once.
87+
88+
Ensures that all the bits form a single word that was present
89+
synchronously in the input clock domain (unlike direct use of
90+
``MultiReg``)."""
91+
def __init__(self, width, idomain, odomain):
92+
self.i = Signal(width)
93+
self.o = Signal(width)
94+
95+
if width == 1:
96+
self.specials += MultiReg(self.i, self.o, odomain)
97+
else:
98+
sync_i = getattr(self.sync, idomain)
99+
sync_o = getattr(self.sync, odomain)
100+
101+
starter = Signal(reset=1)
102+
sync_i += starter.eq(0)
103+
self.submodules._ping = PulseSynchronizer(idomain, odomain)
104+
self.submodules._pong = PulseSynchronizer(odomain, idomain)
105+
self.comb += [
106+
self._ping.i.eq(starter | self._pong.o),
107+
self._pong.i.eq(self._ping.i)
108+
]
109+
110+
ibuffer = Signal(width)
111+
obuffer = Signal(width)
112+
sync_i += If(self._pong.o, ibuffer.eq(self.i))
113+
self.specials += MultiReg(ibuffer, obuffer, odomain)
114+
sync_o += If(self._ping.o, self.o.eq(obuffer))
115+
116+
85117
class GrayCounter(Module):
86118
def __init__(self, width):
87119
self.ce = Signal()

0 commit comments

Comments
 (0)
Please sign in to comment.