genlib: add reset synchronizer
authorSebastien Bourdeauducq <sb@m-labs.hk>
Wed, 6 Aug 2014 11:38:37 +0000 (19:38 +0800)
committerSebastien Bourdeauducq <sb@m-labs.hk>
Wed, 6 Aug 2014 11:38:37 +0000 (19:38 +0800)
mibuild/xilinx_common.py
migen/genlib/resetsync.py [new file with mode: 0644]

index 94ac17b7b07108d74ff1c25aaf8e8979d2cceb13..dbd3decd4ec920a6cd3ab37378bfe9b54eb37e4d 100644 (file)
@@ -4,6 +4,7 @@ from distutils.version import StrictVersion
 from migen.fhdl.std import *
 from migen.fhdl.specials import SynthesisDirective
 from migen.genlib.cdc import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
 from mibuild.generic_platform import GenericPlatform
 from mibuild import tools
 
@@ -66,13 +67,29 @@ class XilinxMultiReg:
        def lower(dr):
                return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
 
+class XilinxAsyncResetSynchronizerImpl(Module):
+       def __init__(self, cd, async_reset):
+               rst1 = Signal()
+               self.specials += [
+                       Instance("FDPE", p_INIT=1, i_D=0, i_PRE=async_reset,
+                               i_C=cd.clk, o_Q=rst1),
+                       Instance("FDPE", p_INIT=1, i_D=rst1, i_PRE=async_reset,
+                               i_C=cd.clk, o_Q=cd.rst)
+               ]
+
+class XilinxAsyncResetSynchronizer:
+       staticmethod
+       def lower(dr):
+               return XilinxAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
+
 class XilinxGenericPlatform(GenericPlatform):
        bitstream_ext = ".bit"
 
        def get_verilog(self, *args, special_overrides=dict(), **kwargs):
                so = {
-                       NoRetiming: XilinxNoRetiming,
-                       MultiReg:   XilinxMultiReg
+                       NoRetiming:                                     XilinxNoRetiming,
+                       MultiReg:                                       XilinxMultiReg,
+                       AsyncResetSynchronizer:         XilinxAsyncResetSynchronizer
                }
                so.update(special_overrides)
                return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
diff --git a/migen/genlib/resetsync.py b/migen/genlib/resetsync.py
new file mode 100644 (file)
index 0000000..43a16cd
--- /dev/null
@@ -0,0 +1,18 @@
+from migen.fhdl.std import *
+from migen.fhdl.specials import Special
+from migen.fhdl.tools import list_signals
+
+class AsyncResetSynchronizer(Special):
+       def __init__(self, cd, async_reset):
+               Special.__init__(self)
+               self.cd = cd
+               self.async_reset = async_reset
+               
+       def iter_expressions(self):
+               yield self.cd, "clk", SPECIAL_INPUT
+               yield self.cd, "rst", SPECIAL_OUTPUT
+               yield self, "async_reset", SPECIAL_INPUT
+
+       @staticmethod
+       def lower(dr):
+               raise NotImplementedError("Attempted to use a reset synchronizer, but platform does not support them")