2018-12-15 07:23:42 -07:00
|
|
|
from .. import *
|
2018-12-12 03:12:35 -07:00
|
|
|
|
|
|
|
|
2019-01-26 11:07:59 -07:00
|
|
|
__all__ = ["MultiReg", "ResetSynchronizer"]
|
2018-12-12 03:12:35 -07:00
|
|
|
|
|
|
|
|
2018-12-12 04:02:13 -07:00
|
|
|
class MultiReg:
|
2018-12-13 04:01:03 -07:00
|
|
|
def __init__(self, i, o, odomain="sync", n=2, reset=0):
|
2018-12-12 03:12:35 -07:00
|
|
|
self.i = i
|
|
|
|
self.o = o
|
|
|
|
self.odomain = odomain
|
|
|
|
|
2018-12-13 04:01:03 -07:00
|
|
|
self._regs = [Signal(self.i.shape(), name="cdc{}".format(i),
|
|
|
|
reset=reset, reset_less=True, attrs={"no_retiming": True})
|
2018-12-12 03:52:32 -07:00
|
|
|
for i in range(n)]
|
2018-12-12 03:12:35 -07:00
|
|
|
|
2019-01-25 19:31:12 -07:00
|
|
|
def elaborate(self, platform):
|
2018-12-12 05:38:24 -07:00
|
|
|
if hasattr(platform, "get_multi_reg"):
|
|
|
|
return platform.get_multi_reg(self)
|
|
|
|
|
|
|
|
m = Module()
|
2018-12-12 03:52:32 -07:00
|
|
|
for i, o in zip((self.i, *self._regs), self._regs):
|
2018-12-12 05:38:24 -07:00
|
|
|
m.d[self.odomain] += o.eq(i)
|
|
|
|
m.d.comb += self.o.eq(self._regs[-1])
|
2019-01-25 19:31:12 -07:00
|
|
|
return m
|
2019-01-26 11:07:59 -07:00
|
|
|
|
|
|
|
|
|
|
|
class ResetSynchronizer:
|
|
|
|
def __init__(self, arst, domain="sync", n=2):
|
|
|
|
self.arst = arst
|
|
|
|
self.domain = domain
|
|
|
|
|
|
|
|
self._regs = [Signal(name="arst{}".format(i), reset=1,
|
|
|
|
attrs={"no_retiming": True})
|
|
|
|
for i in range(n)]
|
|
|
|
|
|
|
|
def elaborate(self, platform):
|
|
|
|
if hasattr(platform, "get_reset_sync"):
|
|
|
|
return platform.get_reset_sync(self)
|
|
|
|
|
|
|
|
m = Module()
|
|
|
|
m.domains += ClockDomain("_reset_sync", async_reset=True)
|
|
|
|
for i, o in zip((0, *self._regs), self._regs):
|
|
|
|
m.d._reset_sync += o.eq(i)
|
|
|
|
m.d.comb += [
|
|
|
|
ClockSignal("_reset_sync").eq(ClockSignal(self.domain)),
|
|
|
|
ResetSignal("_reset_sync").eq(self.arst),
|
|
|
|
ResetSignal(self.domain).eq(self._regs[-1])
|
|
|
|
]
|
|
|
|
return m
|