X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=litex%2Fgen%2Fgenlib%2Fcdc.py;h=3ba1a2627d237579a0eef79b9bd21af72f08f8ea;hb=212e1a7076116a8322d1b2edf51200cfc5c116e7;hp=6e7b0ad8b5a7b947e6d8817168b07efd96dca262;hpb=b708b9cfba5a4a3a34fe71d0601a0acda1a15982;p=litex.git diff --git a/litex/gen/genlib/cdc.py b/litex/gen/genlib/cdc.py index 6e7b0ad8..3ba1a262 100644 --- a/litex/gen/genlib/cdc.py +++ b/litex/gen/genlib/cdc.py @@ -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,