litex/migen/genlib/cdc.py

70 lines
1.5 KiB
Python
Raw Normal View History

2013-02-23 13:03:35 -05:00
from migen.fhdl.structure import *
from migen.fhdl.specials import Special
from migen.fhdl.tools import value_bits_sign, list_signals
class MultiRegImpl:
def __init__(self, i, idomain, o, odomain, n):
self.i = i
self.idomain = idomain
self.o = o
self.odomain = odomain
w, signed = value_bits_sign(self.i)
self.regs = [Signal((w, signed)) for i in range(n)]
def get_fragment(self):
src = self.i
o_sync = []
for reg in self.regs:
o_sync.append(reg.eq(src))
src = reg
comb = [
self.o.eq(src)
]
return Fragment(comb, {self.odomain: o_sync})
class MultiReg(Special):
def __init__(self, i, idomain, o, odomain, n=2):
Special.__init__(self)
self.i = i
self.idomain = idomain
self.o = o
self.odomain = odomain
self.n = n
def list_ios(self, ins, outs, inouts):
r = set()
if ins:
r.update(list_signals(self.i))
if outs:
r.update(list_signals(self.o))
return r
@staticmethod
def lower(dr):
return MultiRegImpl(dr.i, dr.idomain, dr.o, dr.odomain, dr.n)
class PulseSynchronizer:
def __init__(self, idomain, odomain):
self.idomain = idomain
self.odomain = odomain
self.i = Signal()
self.o = Signal()
def get_fragment(self):
toggle_i = Signal()
toggle_o = Signal()
toggle_o_r = Signal()
sync_i = [
If(self.i, toggle_i.eq(~toggle_i))
]
sync_o = [
toggle_o_r.eq(toggle_o)
]
comb = [
self.o.eq(toggle_o ^ toggle_o_r)
]
return Fragment(comb,
{self.idomain: sync_i, self.odomain: sync_o},
specials={MultiReg(toggle_i, self.idomain, toggle_o, self.odomain)})