lib.cdc: add ResetSynchronizer.
This commit is contained in:
parent
e74dbc3377
commit
f44ca291c1
|
@ -1,7 +1,7 @@
|
||||||
from .. import *
|
from .. import *
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["MultiReg"]
|
__all__ = ["MultiReg", "ResetSynchronizer"]
|
||||||
|
|
||||||
|
|
||||||
class MultiReg:
|
class MultiReg:
|
||||||
|
@ -23,3 +23,28 @@ class MultiReg:
|
||||||
m.d[self.odomain] += o.eq(i)
|
m.d[self.odomain] += o.eq(i)
|
||||||
m.d.comb += self.o.eq(self._regs[-1])
|
m.d.comb += self.o.eq(self._regs[-1])
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from .tools import *
|
from .tools import *
|
||||||
from ..hdl.ast import *
|
from ..hdl.ast import *
|
||||||
|
from ..hdl.cd import *
|
||||||
|
from ..hdl.dsl import *
|
||||||
from ..back.pysim import *
|
from ..back.pysim import *
|
||||||
from ..lib.cdc import *
|
from ..lib.cdc import *
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ class MultiRegTestCase(FHDLTestCase):
|
||||||
sim.add_process(process)
|
sim.add_process(process)
|
||||||
sim.run()
|
sim.run()
|
||||||
|
|
||||||
def test_basic(self):
|
def test_reset_value(self):
|
||||||
i = Signal(reset=1)
|
i = Signal(reset=1)
|
||||||
o = Signal()
|
o = Signal()
|
||||||
frag = MultiReg(i, o, reset=1)
|
frag = MultiReg(i, o, reset=1)
|
||||||
|
@ -40,3 +42,42 @@ class MultiRegTestCase(FHDLTestCase):
|
||||||
self.assertEqual((yield o), 0)
|
self.assertEqual((yield o), 0)
|
||||||
sim.add_process(process)
|
sim.add_process(process)
|
||||||
sim.run()
|
sim.run()
|
||||||
|
|
||||||
|
|
||||||
|
class ResetSynchronizerTestCase(FHDLTestCase):
|
||||||
|
def test_basic(self):
|
||||||
|
arst = Signal()
|
||||||
|
m = Module()
|
||||||
|
m.domains += ClockDomain("sync")
|
||||||
|
m.submodules += ResetSynchronizer(arst)
|
||||||
|
s = Signal(reset=1)
|
||||||
|
m.d.sync += s.eq(0)
|
||||||
|
|
||||||
|
with Simulator(m, vcd_file=open("test.vcd", "w")) as sim:
|
||||||
|
sim.add_clock(1e-6)
|
||||||
|
def process():
|
||||||
|
# initial reset
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 0)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
|
||||||
|
yield arst.eq(1)
|
||||||
|
yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield arst.eq(0)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 1)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
self.assertEqual((yield s), 0)
|
||||||
|
yield Tick(); yield Delay(1e-8)
|
||||||
|
sim.add_process(process)
|
||||||
|
sim.run()
|
||||||
|
|
Loading…
Reference in a new issue