Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e2b5d6f82a98
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ee0e7091654e
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Jul 2, 2017

  1. cdc: make pipelined registers reset_less

    data in pipelined registers is guaranteed to be clocked in from source
    signals at "full rate" and fully determined by those source registers.
    in that sense these registers don't hold intrinsic state that needs to
    be reset explicitly. their data can just flow in from the source (which
    is reset).
    having them reset_less delays their reset by one (or a few) clock cycles.
    if the target CD is reset, the data would just be reset for the duration
    of the target CD reset and then ("slowly") transition back to what the
    source CD has.
    control and handshaking logic needs to be reset.
    jordens committed Jul 2, 2017
    Copy the full SHA
    3e72a83 View commit details
  2. cdc: reset GrayCounter gray output early

    * this is not a binary-to-gray encoder, i.e. no pipeline
    * binary and gray would otherwise be out-of-sync for one cycle, even and
    especially in the same clock domain
    * appears to be standard practice to ensure their synchronization
    (http://www.sunburst-design.com/papers/CummingsSNUG2008Boston_CDC.pdf)
    * causes problems in artiq
    jordens committed Jul 2, 2017
    Copy the full SHA
    ee0e709 View commit details
Showing with 12 additions and 11 deletions.
  1. +12 −11 migen/genlib/cdc.py
23 changes: 12 additions & 11 deletions migen/genlib/cdc.py
Original file line number Diff line number Diff line change
@@ -19,7 +19,8 @@ def __init__(self, i, o, odomain, n):
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)]

###

@@ -67,9 +68,9 @@ def __init__(self, idomain, odomain):

###

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)
@@ -88,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)
@@ -108,8 +109,8 @@ def __init__(self, width, idomain, odomain, timeout=128):
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)
@@ -143,7 +144,7 @@ def __init__(self, width):
class GrayDecoder(Module):
def __init__(self, width):
self.i = Signal(width)
self.o = Signal(width)
self.o = Signal(width, reset_less=True)

# # #

@@ -206,7 +207,7 @@ def lcm(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)

# # #

@@ -224,7 +225,7 @@ def __init__(self, iwidth, idomain, owidth, odomain):
]
self.clock_domains += cd_write, cd_read

storage = Signal(2*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//2)
@@ -251,4 +252,4 @@ def __init__(self, iwidth, idomain, owidth, odomain):
cases = {}
for i in range(rdchunks):
cases[i] = [self.o.eq(storage[owidth*i:owidth*(i+1)])]
self.sync.read += Case(rdpointer, cases)
self.sync.read += Case(rdpointer, cases)