@@ -82,6 +82,38 @@ def __init__(self, idomain, odomain):
82
82
self .comb += self .o .eq (toggle_o ^ toggle_o_r )
83
83
84
84
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
+
85
117
class GrayCounter (Module ):
86
118
def __init__ (self , width ):
87
119
self .ce = Signal ()
0 commit comments