|
5 | 5 |
|
6 | 6 |
|
7 | 7 | class MultiReg: |
8 | | - def __init__(self, i, o, odomain="sync", n=2, reset=0): |
| 8 | + """Resynchronise a signal to a different clock domain. |
| 9 | +
|
| 10 | + Consists of a chain of flip-flops. Eliminates metastabilities at the output, but provides |
| 11 | + no other guarantee as to the safe domain-crossing of a signal. |
| 12 | +
|
| 13 | + Parameters |
| 14 | + ---------- |
| 15 | + i : Signal(), in |
| 16 | + Signal to be resynchronised |
| 17 | + o : Signal(), out |
| 18 | + Signal connected to synchroniser output |
| 19 | + odomain : str |
| 20 | + Name of output clock domain |
| 21 | + n : int |
| 22 | + Number of flops between input and output. |
| 23 | + reset : int |
| 24 | + Reset value of the flip-flops. On FPGAs, even if ``reset_less`` is True, the MultiReg is |
| 25 | + still set to this value during initialization. |
| 26 | + reset_less : bool |
| 27 | + If True (the default), this MultiReg is unaffected by ``odomain`` reset. |
| 28 | + See "Note on Reset" below. |
| 29 | +
|
| 30 | + Platform override |
| 31 | + ----------------- |
| 32 | + Define the ``get_multi_reg`` platform metehod to override the implementation of MultiReg, |
| 33 | + e.g. to instantiate library cells directly. |
| 34 | +
|
| 35 | + Note on Reset |
| 36 | + ------------- |
| 37 | + MultiReg is non-resettable by default. Usually this is the safest option; on FPGAs |
| 38 | + the MultiReg will still be initialized to its ``reset`` value when the FPGA loads its |
| 39 | + configuration. |
| 40 | +
|
| 41 | + However, in designs where the value of the MultiReg must be valid immediately after reset, |
| 42 | + consider setting ``reset_less`` to False if any of the following is true: |
| 43 | +
|
| 44 | + - You are targeting an ASIC, or an FPGA that does not allow arbitrary initial flip-flop states; |
| 45 | + - Your design features warm (non-power-on) resets of ``odomain``, so the one-time |
| 46 | + initialization at power on is insufficient; |
| 47 | + - Your design features a sequenced reset, and the MultiReg must maintain its reset value until |
| 48 | + ``odomain`` reset specifically is deasserted. |
| 49 | +
|
| 50 | + MultiReg is reset by the ``odomain`` reset only. |
| 51 | + """ |
| 52 | + def __init__(self, i, o, odomain="sync", n=2, reset=0, reset_less=True): |
9 | 53 | self.i = i |
10 | 54 | self.o = o |
11 | 55 | self.odomain = odomain |
12 | 56 |
|
13 | 57 | self._regs = [Signal(self.i.shape(), name="cdc{}".format(i), |
14 | | - reset=reset, reset_less=True, attrs={"no_retiming": True}) |
| 58 | + reset=reset, reset_less=reset_less, attrs={"no_retiming": True}) |
15 | 59 | for i in range(n)] |
16 | 60 |
|
17 | 61 | def elaborate(self, platform): |
|
0 commit comments