Clock Domain Crossing¶
The torii.lib.cdc module provides building blocks for transferring data between clock domains.
- class torii.lib.cdc.AsyncFFSynchronizer(i: Signal, o: Signal, *, o_domain: str = 'sync', stages: int = 2, async_edge: Literal['pos', 'neg'] = 'pos', max_input_delay: float | None = None) None¶
Synchronize de-assertion of an asynchronous signal.
The signal driven by the
AsyncFFSynchronizeris asserted asynchronously and de-asserted synchronously, eliminating metastability during de-assertion.This synchronizer is primarily useful for resets and reset-like signals.
- Parameters:
i (Signal(1), in) – Asynchronous input signal, to be synchronized.
o (Signal(1), out) – Synchronously released output signal.
o_domain (str) – Name of clock domain to synchronize to.
stages (int, >=2) – Number of synchronization stages between input and output. The lowest safe number is 2, with higher numbers reducing MTBF further, at the cost of increased de-assertion latency.
async_edge (str) – The edge of the input signal which causes the output to be set. Must be one of “pos” or “neg”.
max_input_delay (None | float) – Maximum delay from the input signal’s clock to the first synchronization stage, in seconds. If specified and the platform does not support it, elaboration will fail.
Platform overrides
Define the
get_async_ff_syncplatform method to override the implementation ofAsyncFFSynchronizer, e.g. to instantiate library cells directly.
- class torii.lib.cdc.FFSynchronizer(i: Signal, o: Signal, *, o_domain: str = 'sync', reset: int = 0, reset_less: bool = True, stages: int = 2, max_input_delay: float | None = None) None¶
Resynchronize 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(n), in) – Signal to be resynchronized.
o (Signal(n), out) – Signal connected to synchronizer output.
o_domain (str) – Name of output clock domain.
reset (int) – Reset value of the flip-flops. On FPGAs, even if
reset_lessisTrue, theFFSynchronizeris still set to this value during initialization.reset_less (bool) – If
True(the default), thisFFSynchronizeris unaffected byo_domainreset. See the note below for details.stages (int, >=2) – Number of synchronization stages between input and output. The lowest safe number is 2, with higher numbers reducing MTBF further, at the cost of increased latency.
max_input_delay (None | float) – Maximum delay from the input signal’s clock to the first synchronization stage, in seconds. If specified and the platform does not support it, elaboration will fail.
Note
FFSynchronizeris non-resettable by default. Usually this is the safest option; on FPGAs theFFSynchronizerwill still be initialized to itsresetvalue when the FPGA loads its configuration.However, in designs where the value of the
FFSynchronizermust be valid immediately after reset, consider settingreset_lesstoFalseif 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
o_domain, so the one-time initialization at power on is insufficient;
- Your design features warm (non-power-on) resets of
- Your design features a sequenced reset, and the
FFSynchronizermust maintain its reset value until
o_domainreset specifically is de-asserted.
- Your design features a sequenced reset, and the
FFSynchronizeris reset by theo_domainreset only.Platform overrides
Define the
get_ff_syncplatform method to override the implementation ofFFSynchronizer, e.g. to instantiate library cells directly.
- class torii.lib.cdc.PulseStretcher(cycles: int = 1, domain: str = 'sync') None¶
Stretch a pulse to the given number of cycles.
- Parameters:
- Attributes:
i (Signal) – The input pulse to stretch.
o (Signal) – The stretched pulse.
- class torii.lib.cdc.PulseSynchronizer(i_domain: str, o_domain: str, *, stages: int = 2) None¶
A one-clock pulse on the input produces a one-clock pulse on the output.
If the output clock is faster than the input clock, then the input may be safely asserted at 100% duty cycle. Otherwise, if the clock ratio is
n:1, the input may be asserted at most once in everyninput clocks, else pulses may be dropped. Other than this there is no constraint on the ratio of input and output clock frequency.- Parameters:
- class torii.lib.cdc.ResetSynchronizer(arst: Signal, *, domain: str = 'sync', stages: int = 2, max_input_delay: float | None = None) None¶
Synchronize de-assertion of a clock domain reset.
The reset of the clock domain driven by the
ResetSynchronizeris asserted asynchronously and de-asserted synchronously, eliminating metastability during de-assertion.The driven clock domain could use a reset that is asserted either synchronously or asynchronously; a reset is always de-asserted synchronously. A domain with an asynchronously asserted reset is useful if the clock of the domain may be gated, yet the domain still needs to be reset promptly; otherwise, synchronously asserted reset (the default) should be used.
- Parameters:
arst (Signal(1), in) – Asynchronous reset signal, to be synchronized.
domain (str) – Name of clock domain to reset.
stages (int, >=2) – Number of synchronization stages between input and output. The lowest safe number is 2, with higher numbers reducing MTBF further, at the cost of increased de-assertion latency.
max_input_delay (None | float) – Maximum delay from the input signal’s clock to the first synchronization stage, in seconds. If specified and the platform does not support it, elaboration will fail.
Platform overrides
Define the
get_reset_syncplatform method to override the implementation ofResetSynchronizer, e.g. to instantiate library cells directly.- elaborate(platform) AsyncFFSynchronizer¶
- Return type:
Todo
Document Me