parent
8c30147e39
commit
8f659b6cd6
|
@ -1,5 +1,7 @@
|
||||||
|
import warnings
|
||||||
|
|
||||||
from ...tools import deprecated
|
from ...tools import deprecated
|
||||||
from ...lib.cdc import MultiReg
|
from ...lib.cdc import MultiReg as NativeMultiReg
|
||||||
from ...hdl.ast import *
|
from ...hdl.ast import *
|
||||||
from ..fhdl.module import CompatModule
|
from ..fhdl.module import CompatModule
|
||||||
from ..fhdl.structure import If
|
from ..fhdl.structure import If
|
||||||
|
@ -8,6 +10,16 @@ from ..fhdl.structure import If
|
||||||
__all__ = ["MultiReg", "GrayCounter", "GrayDecoder"]
|
__all__ = ["MultiReg", "GrayCounter", "GrayDecoder"]
|
||||||
|
|
||||||
|
|
||||||
|
class MultiReg(NativeMultiReg):
|
||||||
|
def __init__(self, i, o, odomain="sync", n=2, reset=0):
|
||||||
|
if odomain != "sync":
|
||||||
|
warnings.warn("instead of `MultiReg(..., odomain={!r})`, "
|
||||||
|
"use `MultiReg(..., o_domain={!r})`"
|
||||||
|
.format(odomain, odomain),
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
|
super().__init__(i, o, o_domain=odomain, n=n, reset=reset)
|
||||||
|
|
||||||
|
|
||||||
@deprecated("instead of `migen.genlib.cdc.GrayCounter`, use `nmigen.lib.coding.GrayEncoder`")
|
@deprecated("instead of `migen.genlib.cdc.GrayCounter`, use `nmigen.lib.coding.GrayEncoder`")
|
||||||
class GrayCounter(CompatModule):
|
class GrayCounter(CompatModule):
|
||||||
def __init__(self, width):
|
def __init__(self, width):
|
||||||
|
|
|
@ -16,7 +16,7 @@ class MultiReg(Elaboratable):
|
||||||
Signal to be resynchronised
|
Signal to be resynchronised
|
||||||
o : Signal(), out
|
o : Signal(), out
|
||||||
Signal connected to synchroniser output
|
Signal connected to synchroniser output
|
||||||
odomain : str
|
o_domain : str
|
||||||
Name of output clock domain
|
Name of output clock domain
|
||||||
n : int
|
n : int
|
||||||
Number of flops between input and output.
|
Number of flops between input and output.
|
||||||
|
@ -24,7 +24,7 @@ class MultiReg(Elaboratable):
|
||||||
Reset value of the flip-flops. On FPGAs, even if ``reset_less`` is True, the MultiReg is
|
Reset value of the flip-flops. On FPGAs, even if ``reset_less`` is True, the MultiReg is
|
||||||
still set to this value during initialization.
|
still set to this value during initialization.
|
||||||
reset_less : bool
|
reset_less : bool
|
||||||
If True (the default), this MultiReg is unaffected by ``odomain`` reset.
|
If True (the default), this MultiReg is unaffected by ``o_domain`` reset.
|
||||||
See "Note on Reset" below.
|
See "Note on Reset" below.
|
||||||
|
|
||||||
Platform override
|
Platform override
|
||||||
|
@ -42,17 +42,17 @@ class MultiReg(Elaboratable):
|
||||||
consider setting ``reset_less`` to False if any of the following is true:
|
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;
|
- 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
|
- Your design features warm (non-power-on) resets of ``o_domain``, so the one-time
|
||||||
initialization at power on is insufficient;
|
initialization at power on is insufficient;
|
||||||
- Your design features a sequenced reset, and the MultiReg must maintain its reset value until
|
- Your design features a sequenced reset, and the MultiReg must maintain its reset value until
|
||||||
``odomain`` reset specifically is deasserted.
|
``o_domain`` reset specifically is deasserted.
|
||||||
|
|
||||||
MultiReg is reset by the ``odomain`` reset only.
|
MultiReg is reset by the ``o_domain`` reset only.
|
||||||
"""
|
"""
|
||||||
def __init__(self, i, o, odomain="sync", n=2, reset=0, reset_less=True):
|
def __init__(self, i, o, *, o_domain="sync", n=2, reset=0, reset_less=True):
|
||||||
self.i = i
|
self.i = i
|
||||||
self.o = o
|
self.o = o
|
||||||
self.odomain = odomain
|
self.o_domain = o_domain
|
||||||
|
|
||||||
self._regs = [Signal(self.i.shape(), name="cdc{}".format(i), reset=reset,
|
self._regs = [Signal(self.i.shape(), name="cdc{}".format(i), reset=reset,
|
||||||
reset_less=reset_less)
|
reset_less=reset_less)
|
||||||
|
@ -64,7 +64,7 @@ class MultiReg(Elaboratable):
|
||||||
|
|
||||||
m = Module()
|
m = Module()
|
||||||
for i, o in zip((self.i, *self._regs), self._regs):
|
for i, o in zip((self.i, *self._regs), self._regs):
|
||||||
m.d[self.odomain] += o.eq(i)
|
m.d[self.o_domain] += 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
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
|
||||||
produce_enc = m.submodules.produce_enc = \
|
produce_enc = m.submodules.produce_enc = \
|
||||||
GrayEncoder(self._ctr_bits)
|
GrayEncoder(self._ctr_bits)
|
||||||
produce_cdc = m.submodules.produce_cdc = \
|
produce_cdc = m.submodules.produce_cdc = \
|
||||||
MultiReg(produce_w_gry, produce_r_gry, odomain="read")
|
MultiReg(produce_w_gry, produce_r_gry, o_domain="read")
|
||||||
m.d.comb += produce_enc.i.eq(produce_w_nxt),
|
m.d.comb += produce_enc.i.eq(produce_w_nxt),
|
||||||
m.d.write += produce_w_gry.eq(produce_enc.o)
|
m.d.write += produce_w_gry.eq(produce_enc.o)
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
|
||||||
consume_enc = m.submodules.consume_enc = \
|
consume_enc = m.submodules.consume_enc = \
|
||||||
GrayEncoder(self._ctr_bits)
|
GrayEncoder(self._ctr_bits)
|
||||||
consume_cdc = m.submodules.consume_cdc = \
|
consume_cdc = m.submodules.consume_cdc = \
|
||||||
MultiReg(consume_r_gry, consume_w_gry, odomain="write")
|
MultiReg(consume_r_gry, consume_w_gry, o_domain="write")
|
||||||
m.d.comb += consume_enc.i.eq(consume_r_nxt)
|
m.d.comb += consume_enc.i.eq(consume_r_nxt)
|
||||||
m.d.read += consume_r_gry.eq(consume_enc.o)
|
m.d.read += consume_r_gry.eq(consume_enc.o)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue