lib.cdc: add optional reset to MultiReg, and document its use cases.
This commit is contained in:
parent
a57c72d606
commit
23a07b955f
|
@ -5,13 +5,57 @@ __all__ = ["MultiReg", "ResetSynchronizer"]
|
|||
|
||||
|
||||
class MultiReg:
|
||||
def __init__(self, i, o, odomain="sync", n=2, reset=0):
|
||||
"""Resynchronise a signal to a different clock domain.
|
||||
|
||||
Consists of a chain of flip-flops. Eliminates metastabilities at the output, but provides
|
||||
no other guarantee as to the safe domain-crossing of a signal.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
i : Signal(), in
|
||||
Signal to be resynchronised
|
||||
o : Signal(), out
|
||||
Signal connected to synchroniser output
|
||||
odomain : str
|
||||
Name of output clock domain
|
||||
n : int
|
||||
Number of flops between input and output.
|
||||
reset : int
|
||||
Reset value of the flip-flops. On FPGAs, even if ``reset_less`` is True, the MultiReg is
|
||||
still set to this value during initialization.
|
||||
reset_less : bool
|
||||
If True (the default), this MultiReg is unaffected by ``odomain`` reset.
|
||||
See "Note on Reset" below.
|
||||
|
||||
Platform override
|
||||
-----------------
|
||||
Define the ``get_multi_reg`` platform metehod to override the implementation of MultiReg,
|
||||
e.g. to instantiate library cells directly.
|
||||
|
||||
Note on Reset
|
||||
-------------
|
||||
MultiReg is non-resettable by default. Usually this is the safest option; on FPGAs
|
||||
the MultiReg will still be initialized to its ``reset`` value when the FPGA loads its
|
||||
configuration.
|
||||
|
||||
However, in designs where the value of the MultiReg must be valid immediately after reset,
|
||||
consider setting ``reset_less`` to False if any of the following is true:
|
||||
|
||||
- You are targeting an ASIC, or an FPGA that does not allow arbitrary initial flip-flop states;
|
||||
- Your design features warm (non-power-on) resets of ``odomain``, so the one-time
|
||||
initialization at power on is insufficient;
|
||||
- Your design features a sequenced reset, and the MultiReg must maintain its reset value until
|
||||
``odomain`` reset specifically is deasserted.
|
||||
|
||||
MultiReg is reset by the ``odomain`` reset only.
|
||||
"""
|
||||
def __init__(self, i, o, odomain="sync", n=2, reset=0, reset_less=True):
|
||||
self.i = i
|
||||
self.o = o
|
||||
self.odomain = odomain
|
||||
|
||||
self._regs = [Signal(self.i.shape(), name="cdc{}".format(i),
|
||||
reset=reset, reset_less=True, attrs={"no_retiming": True})
|
||||
reset=reset, reset_less=reset_less, attrs={"no_retiming": True})
|
||||
for i in range(n)]
|
||||
|
||||
def elaborate(self, platform):
|
||||
|
|
Loading…
Reference in a new issue