bump to 0.2.dev
[litex.git] / litex / gen / genlib / cdc.py
index 6e7b0ad8b5a7b947e6d8817168b07efd96dca262..3ba1a2627d237579a0eef79b9bd21af72f08f8ea 100644 (file)
@@ -1,12 +1,13 @@
 """
 Clock domain crossing module
 """
-from fractions import gcd
+from math import gcd
 
 from litex.gen.fhdl.structure import *
 from litex.gen.fhdl.module import Module
 from litex.gen.fhdl.specials import Special, Memory
 from litex.gen.fhdl.bitcontainer import value_bits_sign
+from litex.gen.fhdl.decorators import ClockDomainsRenamer
 from litex.gen.genlib.misc import WaitTimer
 from litex.gen.genlib.resetsync import AsyncResetSynchronizer
 
@@ -18,7 +19,8 @@ class MultiRegImpl(Module):
         self.odomain = odomain
 
         w, signed = value_bits_sign(self.i)
-        self.regs = [Signal((w, signed)) for i in range(n)]
+        self.regs = [Signal((w, signed), reset_less=True)
+                for i in range(n)]
 
         ###
 
@@ -66,9 +68,9 @@ class PulseSynchronizer(Module):
 
         ###
 
-        toggle_i = Signal()
-        toggle_o = Signal()
-        toggle_o_r = Signal()
+        toggle_i = Signal(reset_less=True)
+        toggle_o = Signal()  # registered reset_less by MultiReg
+        toggle_o_r = Signal(reset_less=True)
 
         sync_i = getattr(self.sync, idomain)
         sync_o = getattr(self.sync, odomain)
@@ -87,7 +89,7 @@ class BusSynchronizer(Module):
     ``MultiReg``)."""
     def __init__(self, width, idomain, odomain, timeout=128):
         self.i = Signal(width)
-        self.o = Signal(width)
+        self.o = Signal(width, reset_less=True)
 
         if width == 1:
             self.specials += MultiReg(self.i, self.o, odomain)
@@ -99,15 +101,16 @@ class BusSynchronizer(Module):
             sync_i += starter.eq(0)
             self.submodules._ping = PulseSynchronizer(idomain, odomain)
             self.submodules._pong = PulseSynchronizer(odomain, idomain)
-            self.submodules._timeout = WaitTimer(timeout)
+            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.i)
             ]
 
-            ibuffer = Signal(width)
-            obuffer = Signal(width)
+            ibuffer = Signal(width, reset_less=True)
+            obuffer = Signal(width)  # registered reset_less by MultiReg
             sync_i += If(self._pong.o, ibuffer.eq(self.i))
             ibuffer.attr.add("no_retiming")
             self.specials += MultiReg(ibuffer, obuffer, odomain)
@@ -141,7 +144,7 @@ class GrayCounter(Module):
 class GrayDecoder(Module):
     def __init__(self, width):
         self.i = Signal(width)
-        self.o = Signal(width)
+        self.o = Signal(width, reset_less=True)
 
         # # #
 
@@ -198,35 +201,33 @@ class ElasticBuffer(Module):
 
 def lcm(a, b):
     """Compute the lowest common multiple of a and b"""
-    return int(a * b / gcd(a, b))
+    return (a*b)//gcd(a, b)
 
 
 class Gearbox(Module):
     def __init__(self, iwidth, idomain, owidth, odomain):
         self.i = Signal(iwidth)
-        self.o = Signal(owidth)
+        self.o = Signal(owidth, reset_less=True)
 
         # # #
 
-        reset = Signal()
+        rst = Signal()
         cd_write = ClockDomain()
         cd_read = ClockDomain()
         self.comb += [
+            rst.eq(ResetSignal(idomain) | ResetSignal(odomain)),
             cd_write.clk.eq(ClockSignal(idomain)),
             cd_read.clk.eq(ClockSignal(odomain)),
-            reset.eq(ResetSignal(idomain) | ResetSignal(odomain))
-        ]
-        self.specials += [
-            AsyncResetSynchronizer(cd_write, reset),
-            AsyncResetSynchronizer(cd_read, reset)
+            cd_write.rst.eq(rst),
+            cd_read.rst.eq(rst)
         ]
         self.clock_domains += cd_write, cd_read
 
-        storage = Signal(lcm(iwidth, owidth))
+        storage = Signal(2*lcm(iwidth, owidth), reset_less=True)
         wrchunks = len(storage)//iwidth
         rdchunks = len(storage)//owidth
-        wrpointer = Signal(max=wrchunks, reset=0 if iwidth > owidth else wrchunks-1)
-        rdpointer = Signal(max=rdchunks, reset=rdchunks-1 if iwidth > owidth else 0)
+        wrpointer = Signal(max=wrchunks, reset=0 if iwidth > owidth else wrchunks//2)
+        rdpointer = Signal(max=rdchunks, reset=rdchunks//2 if iwidth > owidth else 0)
 
         self.sync.write += \
             If(wrpointer == wrchunks-1,