Rename nMigen to Amaranth HDL.
This commit is contained in:
parent
0b28a97ca0
commit
909a3b8be7
200 changed files with 14493 additions and 14451 deletions
|
|
@ -0,0 +1,6 @@
|
|||
from amaranth.compat.genlib import *
|
||||
|
||||
|
||||
import warnings
|
||||
warnings.warn("instead of nmigen.compat.genlib, use amaranth.compat.genlib",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
@ -1,74 +1,7 @@
|
|||
from amaranth.compat.genlib.cdc import *
|
||||
from amaranth.compat.genlib.cdc import __all__
|
||||
|
||||
|
||||
import warnings
|
||||
|
||||
from ..._utils import deprecated
|
||||
from ...lib.cdc import FFSynchronizer as NativeFFSynchronizer
|
||||
from ...lib.cdc import PulseSynchronizer as NativePulseSynchronizer
|
||||
from ...hdl.ast import *
|
||||
from ..fhdl.module import CompatModule
|
||||
from ..fhdl.structure import If
|
||||
|
||||
|
||||
__all__ = ["MultiReg", "PulseSynchronizer", "GrayCounter", "GrayDecoder"]
|
||||
|
||||
|
||||
class MultiReg(NativeFFSynchronizer):
|
||||
def __init__(self, i, o, odomain="sync", n=2, reset=0):
|
||||
old_opts = []
|
||||
new_opts = []
|
||||
if odomain != "sync":
|
||||
old_opts.append(", odomain={!r}".format(odomain))
|
||||
new_opts.append(", o_domain={!r}".format(odomain))
|
||||
if n != 2:
|
||||
old_opts.append(", n={!r}".format(n))
|
||||
new_opts.append(", stages={!r}".format(n))
|
||||
warnings.warn("instead of `MultiReg(...{})`, use `FFSynchronizer(...{})`"
|
||||
.format("".join(old_opts), "".join(new_opts)),
|
||||
DeprecationWarning, stacklevel=2)
|
||||
super().__init__(i, o, o_domain=odomain, stages=n, reset=reset)
|
||||
self.odomain = odomain
|
||||
|
||||
|
||||
@deprecated("instead of `migen.genlib.cdc.PulseSynchronizer`, use `nmigen.lib.cdc.PulseSynchronizer`")
|
||||
class PulseSynchronizer(NativePulseSynchronizer):
|
||||
def __init__(self, idomain, odomain):
|
||||
super().__init__(i_domain=idomain, o_domain=odomain)
|
||||
|
||||
|
||||
@deprecated("instead of `migen.genlib.cdc.GrayCounter`, use `nmigen.lib.coding.GrayEncoder`")
|
||||
class GrayCounter(CompatModule):
|
||||
def __init__(self, width):
|
||||
self.ce = Signal()
|
||||
self.q = Signal(width)
|
||||
self.q_next = Signal(width)
|
||||
self.q_binary = Signal(width)
|
||||
self.q_next_binary = Signal(width)
|
||||
|
||||
###
|
||||
|
||||
self.comb += [
|
||||
If(self.ce,
|
||||
self.q_next_binary.eq(self.q_binary + 1)
|
||||
).Else(
|
||||
self.q_next_binary.eq(self.q_binary)
|
||||
),
|
||||
self.q_next.eq(self.q_next_binary ^ self.q_next_binary[1:])
|
||||
]
|
||||
self.sync += [
|
||||
self.q_binary.eq(self.q_next_binary),
|
||||
self.q.eq(self.q_next)
|
||||
]
|
||||
|
||||
|
||||
@deprecated("instead of `migen.genlib.cdc.GrayDecoder`, use `nmigen.lib.coding.GrayDecoder`")
|
||||
class GrayDecoder(CompatModule):
|
||||
def __init__(self, width):
|
||||
self.i = Signal(width)
|
||||
self.o = Signal(width, reset_less=True)
|
||||
|
||||
# # #
|
||||
|
||||
o_comb = Signal(width)
|
||||
self.comb += o_comb[-1].eq(self.i[-1])
|
||||
for i in reversed(range(width-1)):
|
||||
self.comb += o_comb[i].eq(o_comb[i+1] ^ self.i[i])
|
||||
self.sync += self.o.eq(o_comb)
|
||||
warnings.warn("instead of nmigen.compat.genlib.cdc, use amaranth.compat.genlib.cdc",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
from ...lib.coding import *
|
||||
from amaranth.compat.genlib.coding import *
|
||||
from amaranth.compat.genlib.coding import __all__
|
||||
|
||||
|
||||
__all__ = ["Encoder", "PriorityEncoder", "Decoder", "PriorityDecoder"]
|
||||
import warnings
|
||||
warnings.warn("instead of nmigen.compat.genlib.coding, use amaranth.compat.genlib.coding",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
|
|
@ -1,147 +1,7 @@
|
|||
from ..._utils import deprecated, extend
|
||||
from ...lib.fifo import (FIFOInterface as NativeFIFOInterface,
|
||||
SyncFIFO as NativeSyncFIFO, SyncFIFOBuffered as NativeSyncFIFOBuffered,
|
||||
AsyncFIFO as NativeAsyncFIFO, AsyncFIFOBuffered as NativeAsyncFIFOBuffered)
|
||||
from amaranth.compat.genlib.fifo import *
|
||||
from amaranth.compat.genlib.fifo import __all__
|
||||
|
||||
|
||||
__all__ = ["_FIFOInterface", "SyncFIFO", "SyncFIFOBuffered", "AsyncFIFO", "AsyncFIFOBuffered"]
|
||||
|
||||
|
||||
class CompatFIFOInterface(NativeFIFOInterface):
|
||||
@deprecated("attribute `fwft` must be provided to FIFOInterface constructor")
|
||||
def __init__(self, width, depth):
|
||||
super().__init__(width=width, depth=depth, fwft=False)
|
||||
del self.fwft
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@property
|
||||
@deprecated("instead of `fifo.din`, use `fifo.w_data`")
|
||||
def din(self):
|
||||
return self.w_data
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@NativeFIFOInterface.din.setter
|
||||
@deprecated("instead of `fifo.din = x`, use `fifo.w_data = x`")
|
||||
def din(self, w_data):
|
||||
self.w_data = w_data
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@property
|
||||
@deprecated("instead of `fifo.writable`, use `fifo.w_rdy`")
|
||||
def writable(self):
|
||||
return self.w_rdy
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@NativeFIFOInterface.writable.setter
|
||||
@deprecated("instead of `fifo.writable = x`, use `fifo.w_rdy = x`")
|
||||
def writable(self, w_rdy):
|
||||
self.w_rdy = w_rdy
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@property
|
||||
@deprecated("instead of `fifo.we`, use `fifo.w_en`")
|
||||
def we(self):
|
||||
return self.w_en
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@NativeFIFOInterface.we.setter
|
||||
@deprecated("instead of `fifo.we = x`, use `fifo.w_en = x`")
|
||||
def we(self, w_en):
|
||||
self.w_en = w_en
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@property
|
||||
@deprecated("instead of `fifo.dout`, use `fifo.r_data`")
|
||||
def dout(self):
|
||||
return self.r_data
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@NativeFIFOInterface.dout.setter
|
||||
@deprecated("instead of `fifo.dout = x`, use `fifo.r_data = x`")
|
||||
def dout(self, r_data):
|
||||
self.r_data = r_data
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@property
|
||||
@deprecated("instead of `fifo.readable`, use `fifo.r_rdy`")
|
||||
def readable(self):
|
||||
return self.r_rdy
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@NativeFIFOInterface.readable.setter
|
||||
@deprecated("instead of `fifo.readable = x`, use `fifo.r_rdy = x`")
|
||||
def readable(self, r_rdy):
|
||||
self.r_rdy = r_rdy
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@property
|
||||
@deprecated("instead of `fifo.re`, use `fifo.r_en`")
|
||||
def re(self):
|
||||
return self.r_en
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
@NativeFIFOInterface.re.setter
|
||||
@deprecated("instead of `fifo.re = x`, use `fifo.r_en = x`")
|
||||
def re(self, r_en):
|
||||
self.r_en = r_en
|
||||
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
def read(self):
|
||||
"""Read method for simulation."""
|
||||
assert (yield self.r_rdy)
|
||||
value = (yield self.r_data)
|
||||
yield self.r_en.eq(1)
|
||||
yield
|
||||
yield self.r_en.eq(0)
|
||||
yield
|
||||
return value
|
||||
|
||||
@extend(NativeFIFOInterface)
|
||||
def write(self, data):
|
||||
"""Write method for simulation."""
|
||||
assert (yield self.w_rdy)
|
||||
yield self.w_data.eq(data)
|
||||
yield self.w_en.eq(1)
|
||||
yield
|
||||
yield self.w_en.eq(0)
|
||||
yield
|
||||
|
||||
|
||||
class CompatSyncFIFO(NativeSyncFIFO):
|
||||
def __init__(self, width, depth, fwft=True):
|
||||
super().__init__(width=width, depth=depth, fwft=fwft)
|
||||
|
||||
|
||||
class CompatSyncFIFOBuffered(NativeSyncFIFOBuffered):
|
||||
def __init__(self, width, depth):
|
||||
super().__init__(width=width, depth=depth)
|
||||
|
||||
|
||||
class CompatAsyncFIFO(NativeAsyncFIFO):
|
||||
def __init__(self, width, depth):
|
||||
super().__init__(width=width, depth=depth)
|
||||
|
||||
|
||||
class CompatAsyncFIFOBuffered(NativeAsyncFIFOBuffered):
|
||||
def __init__(self, width, depth):
|
||||
super().__init__(width=width, depth=depth)
|
||||
|
||||
|
||||
_FIFOInterface = CompatFIFOInterface
|
||||
SyncFIFO = CompatSyncFIFO
|
||||
SyncFIFOBuffered = CompatSyncFIFOBuffered
|
||||
AsyncFIFO = CompatAsyncFIFO
|
||||
AsyncFIFOBuffered = CompatAsyncFIFOBuffered
|
||||
import warnings
|
||||
warnings.warn("instead of nmigen.compat.genlib.fifo, use amaranth.compat.genlib.fifo",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
|
|
@ -1,193 +1,7 @@
|
|||
from collections import OrderedDict
|
||||
|
||||
from ..._utils import deprecated, _ignore_deprecated
|
||||
from ...hdl.xfrm import ValueTransformer, StatementTransformer
|
||||
from ...hdl.ast import *
|
||||
from ...hdl.ast import Signal as NativeSignal
|
||||
from ..fhdl.module import CompatModule, CompatFinalizeError
|
||||
from ..fhdl.structure import Signal, If, Case
|
||||
from amaranth.compat.genlib.fsm import *
|
||||
from amaranth.compat.genlib.fsm import __all__
|
||||
|
||||
|
||||
__all__ = ["AnonymousState", "NextState", "NextValue", "FSM"]
|
||||
|
||||
|
||||
class AnonymousState:
|
||||
pass
|
||||
|
||||
|
||||
class NextState(Statement):
|
||||
def __init__(self, state):
|
||||
super().__init__()
|
||||
self.state = state
|
||||
|
||||
|
||||
class NextValue(Statement):
|
||||
def __init__(self, target, value):
|
||||
super().__init__()
|
||||
self.target = target
|
||||
self.value = value
|
||||
|
||||
|
||||
def _target_eq(a, b):
|
||||
if type(a) != type(b):
|
||||
return False
|
||||
ty = type(a)
|
||||
if ty == Const:
|
||||
return a.value == b.value
|
||||
elif ty == NativeSignal or ty == Signal:
|
||||
return a is b
|
||||
elif ty == Cat:
|
||||
return all(_target_eq(x, y) for x, y in zip(a.l, b.l))
|
||||
elif ty == Slice:
|
||||
return (_target_eq(a.value, b.value)
|
||||
and a.start == b.start
|
||||
and a.stop == b.stop)
|
||||
elif ty == Part:
|
||||
return (_target_eq(a.value, b.value)
|
||||
and _target_eq(a.offset == b.offset)
|
||||
and a.width == b.width)
|
||||
elif ty == ArrayProxy:
|
||||
return (all(_target_eq(x, y) for x, y in zip(a.choices, b.choices))
|
||||
and _target_eq(a.key, b.key))
|
||||
else:
|
||||
raise ValueError("NextValue cannot be used with target type '{}'"
|
||||
.format(ty))
|
||||
|
||||
|
||||
class _LowerNext(ValueTransformer, StatementTransformer):
|
||||
def __init__(self, next_state_signal, encoding, aliases):
|
||||
self.next_state_signal = next_state_signal
|
||||
self.encoding = encoding
|
||||
self.aliases = aliases
|
||||
# (target, next_value_ce, next_value)
|
||||
self.registers = []
|
||||
|
||||
def _get_register_control(self, target):
|
||||
for x in self.registers:
|
||||
if _target_eq(target, x[0]):
|
||||
return x[1], x[2]
|
||||
raise KeyError
|
||||
|
||||
def on_unknown_statement(self, node):
|
||||
if isinstance(node, NextState):
|
||||
try:
|
||||
actual_state = self.aliases[node.state]
|
||||
except KeyError:
|
||||
actual_state = node.state
|
||||
return self.next_state_signal.eq(self.encoding[actual_state])
|
||||
elif isinstance(node, NextValue):
|
||||
try:
|
||||
next_value_ce, next_value = self._get_register_control(node.target)
|
||||
except KeyError:
|
||||
related = node.target if isinstance(node.target, Signal) else None
|
||||
next_value = Signal(node.target.shape(),
|
||||
name=None if related is None else "{}_fsm_next".format(related.name))
|
||||
next_value_ce = Signal(
|
||||
name=None if related is None else "{}_fsm_next_ce".format(related.name))
|
||||
self.registers.append((node.target, next_value_ce, next_value))
|
||||
return next_value.eq(node.value), next_value_ce.eq(1)
|
||||
else:
|
||||
return node
|
||||
|
||||
|
||||
@deprecated("instead of `migen.genlib.fsm.FSM()`, use `with m.FSM():`; note that there is no "
|
||||
"replacement for `{before,after}_{entering,leaving}` and `delayed_enter` methods")
|
||||
class FSM(CompatModule):
|
||||
def __init__(self, reset_state=None):
|
||||
self.actions = OrderedDict()
|
||||
self.state_aliases = dict()
|
||||
self.reset_state = reset_state
|
||||
|
||||
self.before_entering_signals = OrderedDict()
|
||||
self.before_leaving_signals = OrderedDict()
|
||||
self.after_entering_signals = OrderedDict()
|
||||
self.after_leaving_signals = OrderedDict()
|
||||
|
||||
def act(self, state, *statements):
|
||||
if self.finalized:
|
||||
raise CompatFinalizeError
|
||||
if self.reset_state is None:
|
||||
self.reset_state = state
|
||||
if state not in self.actions:
|
||||
self.actions[state] = []
|
||||
self.actions[state] += statements
|
||||
|
||||
def delayed_enter(self, name, target, delay):
|
||||
if self.finalized:
|
||||
raise CompatFinalizeError
|
||||
if delay > 0:
|
||||
state = name
|
||||
for i in range(delay):
|
||||
if i == delay - 1:
|
||||
next_state = target
|
||||
else:
|
||||
next_state = AnonymousState()
|
||||
self.act(state, NextState(next_state))
|
||||
state = next_state
|
||||
else:
|
||||
self.state_aliases[name] = target
|
||||
|
||||
def ongoing(self, state):
|
||||
is_ongoing = Signal()
|
||||
self.act(state, is_ongoing.eq(1))
|
||||
return is_ongoing
|
||||
|
||||
def _get_signal(self, d, state):
|
||||
if state not in self.actions:
|
||||
self.actions[state] = []
|
||||
try:
|
||||
return d[state]
|
||||
except KeyError:
|
||||
is_el = Signal()
|
||||
d[state] = is_el
|
||||
return is_el
|
||||
|
||||
def before_entering(self, state):
|
||||
return self._get_signal(self.before_entering_signals, state)
|
||||
|
||||
def before_leaving(self, state):
|
||||
return self._get_signal(self.before_leaving_signals, state)
|
||||
|
||||
def after_entering(self, state):
|
||||
signal = self._get_signal(self.after_entering_signals, state)
|
||||
self.sync += signal.eq(self.before_entering(state))
|
||||
return signal
|
||||
|
||||
def after_leaving(self, state):
|
||||
signal = self._get_signal(self.after_leaving_signals, state)
|
||||
self.sync += signal.eq(self.before_leaving(state))
|
||||
return signal
|
||||
|
||||
@_ignore_deprecated
|
||||
def do_finalize(self):
|
||||
nstates = len(self.actions)
|
||||
self.encoding = dict((s, n) for n, s in enumerate(self.actions.keys()))
|
||||
self.decoding = {n: s for s, n in self.encoding.items()}
|
||||
|
||||
decoder = lambda n: "{}/{}".format(self.decoding[n], n)
|
||||
self.state = Signal(range(nstates), reset=self.encoding[self.reset_state], decoder=decoder)
|
||||
self.next_state = Signal.like(self.state)
|
||||
|
||||
for state, signal in self.before_leaving_signals.items():
|
||||
encoded = self.encoding[state]
|
||||
self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded))
|
||||
if self.reset_state in self.after_entering_signals:
|
||||
self.after_entering_signals[self.reset_state].reset = 1
|
||||
for state, signal in self.before_entering_signals.items():
|
||||
encoded = self.encoding[state]
|
||||
self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded))
|
||||
|
||||
self._finalize_sync(self._lower_controls())
|
||||
|
||||
def _lower_controls(self):
|
||||
return _LowerNext(self.next_state, self.encoding, self.state_aliases)
|
||||
|
||||
def _finalize_sync(self, ls):
|
||||
cases = dict((self.encoding[k], ls.on_statement(v)) for k, v in self.actions.items() if v)
|
||||
self.comb += [
|
||||
self.next_state.eq(self.state),
|
||||
Case(self.state, cases).makedefault(self.encoding[self.reset_state])
|
||||
]
|
||||
self.sync += self.state.eq(self.next_state)
|
||||
for register, next_value_ce, next_value in ls.registers:
|
||||
self.sync += If(next_value_ce, register.eq(next_value))
|
||||
import warnings
|
||||
warnings.warn("instead of nmigen.compat.genlib.fsm, use amaranth.compat.genlib.fsm",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
|
|
@ -1,195 +1,6 @@
|
|||
from ...tracer import *
|
||||
from ..fhdl.structure import *
|
||||
|
||||
from functools import reduce
|
||||
from operator import or_
|
||||
from amaranth.compat.genlib.record import *
|
||||
|
||||
|
||||
(DIR_NONE, DIR_S_TO_M, DIR_M_TO_S) = range(3)
|
||||
|
||||
# Possible layout elements:
|
||||
# 1. (name, size)
|
||||
# 2. (name, size, direction)
|
||||
# 3. (name, sublayout)
|
||||
# size can be an int, or a (int, bool) tuple for signed numbers
|
||||
# sublayout must be a list
|
||||
|
||||
|
||||
def set_layout_parameters(layout, **layout_dict):
|
||||
def resolve(p):
|
||||
if isinstance(p, str):
|
||||
try:
|
||||
return layout_dict[p]
|
||||
except KeyError:
|
||||
return p
|
||||
else:
|
||||
return p
|
||||
|
||||
r = []
|
||||
for f in layout:
|
||||
if isinstance(f[1], (int, tuple, str)): # cases 1/2
|
||||
if len(f) == 3:
|
||||
r.append((f[0], resolve(f[1]), f[2]))
|
||||
else:
|
||||
r.append((f[0], resolve(f[1])))
|
||||
elif isinstance(f[1], list): # case 3
|
||||
r.append((f[0], set_layout_parameters(f[1], **layout_dict)))
|
||||
else:
|
||||
raise TypeError
|
||||
return r
|
||||
|
||||
|
||||
def layout_len(layout):
|
||||
r = 0
|
||||
for f in layout:
|
||||
if isinstance(f[1], (int, tuple)): # cases 1/2
|
||||
if len(f) == 3:
|
||||
fname, fsize, fdirection = f
|
||||
else:
|
||||
fname, fsize = f
|
||||
elif isinstance(f[1], list): # case 3
|
||||
fname, fsublayout = f
|
||||
fsize = layout_len(fsublayout)
|
||||
else:
|
||||
raise TypeError
|
||||
if isinstance(fsize, tuple):
|
||||
r += fsize[0]
|
||||
else:
|
||||
r += fsize
|
||||
return r
|
||||
|
||||
|
||||
def layout_get(layout, name):
|
||||
for f in layout:
|
||||
if f[0] == name:
|
||||
return f
|
||||
raise KeyError(name)
|
||||
|
||||
|
||||
def layout_partial(layout, *elements):
|
||||
r = []
|
||||
for path in elements:
|
||||
path_s = path.split("/")
|
||||
last = path_s.pop()
|
||||
copy_ref = layout
|
||||
insert_ref = r
|
||||
for hop in path_s:
|
||||
name, copy_ref = layout_get(copy_ref, hop)
|
||||
try:
|
||||
name, insert_ref = layout_get(insert_ref, hop)
|
||||
except KeyError:
|
||||
new_insert_ref = []
|
||||
insert_ref.append((hop, new_insert_ref))
|
||||
insert_ref = new_insert_ref
|
||||
insert_ref.append(layout_get(copy_ref, last))
|
||||
return r
|
||||
|
||||
|
||||
class Record:
|
||||
def __init__(self, layout, name=None, **kwargs):
|
||||
try:
|
||||
self.name = get_var_name()
|
||||
except NameNotFound:
|
||||
self.name = ""
|
||||
self.layout = layout
|
||||
|
||||
if self.name:
|
||||
prefix = self.name + "_"
|
||||
else:
|
||||
prefix = ""
|
||||
for f in self.layout:
|
||||
if isinstance(f[1], (int, tuple)): # cases 1/2
|
||||
if(len(f) == 3):
|
||||
fname, fsize, fdirection = f
|
||||
else:
|
||||
fname, fsize = f
|
||||
finst = Signal(fsize, name=prefix + fname, **kwargs)
|
||||
elif isinstance(f[1], list): # case 3
|
||||
fname, fsublayout = f
|
||||
finst = Record(fsublayout, prefix + fname, **kwargs)
|
||||
else:
|
||||
raise TypeError
|
||||
setattr(self, fname, finst)
|
||||
|
||||
def eq(self, other):
|
||||
return [getattr(self, f[0]).eq(getattr(other, f[0]))
|
||||
for f in self.layout if hasattr(other, f[0])]
|
||||
|
||||
def iter_flat(self):
|
||||
for f in self.layout:
|
||||
e = getattr(self, f[0])
|
||||
if isinstance(e, Signal):
|
||||
if len(f) == 3:
|
||||
yield e, f[2]
|
||||
else:
|
||||
yield e, DIR_NONE
|
||||
elif isinstance(e, Record):
|
||||
yield from e.iter_flat()
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
def flatten(self):
|
||||
return [signal for signal, direction in self.iter_flat()]
|
||||
|
||||
def raw_bits(self):
|
||||
return Cat(*self.flatten())
|
||||
|
||||
def connect(self, *slaves, keep=None, omit=None):
|
||||
if keep is None:
|
||||
_keep = set([f[0] for f in self.layout])
|
||||
elif isinstance(keep, list):
|
||||
_keep = set(keep)
|
||||
else:
|
||||
_keep = keep
|
||||
if omit is None:
|
||||
_omit = set()
|
||||
elif isinstance(omit, list):
|
||||
_omit = set(omit)
|
||||
else:
|
||||
_omit = omit
|
||||
|
||||
_keep = _keep - _omit
|
||||
|
||||
r = []
|
||||
for f in self.layout:
|
||||
field = f[0]
|
||||
self_e = getattr(self, field)
|
||||
if isinstance(self_e, Signal):
|
||||
if field in _keep:
|
||||
direction = f[2]
|
||||
if direction == DIR_M_TO_S:
|
||||
r += [getattr(slave, field).eq(self_e) for slave in slaves]
|
||||
elif direction == DIR_S_TO_M:
|
||||
r.append(self_e.eq(reduce(or_, [getattr(slave, field) for slave in slaves])))
|
||||
else:
|
||||
raise TypeError
|
||||
else:
|
||||
for slave in slaves:
|
||||
r += self_e.connect(getattr(slave, field), keep=keep, omit=omit)
|
||||
return r
|
||||
|
||||
def connect_flat(self, *slaves):
|
||||
r = []
|
||||
iter_slaves = [slave.iter_flat() for slave in slaves]
|
||||
for m_signal, m_direction in self.iter_flat():
|
||||
if m_direction == DIR_M_TO_S:
|
||||
for iter_slave in iter_slaves:
|
||||
s_signal, s_direction = next(iter_slave)
|
||||
assert(s_direction == DIR_M_TO_S)
|
||||
r.append(s_signal.eq(m_signal))
|
||||
elif m_direction == DIR_S_TO_M:
|
||||
s_signals = []
|
||||
for iter_slave in iter_slaves:
|
||||
s_signal, s_direction = next(iter_slave)
|
||||
assert(s_direction == DIR_S_TO_M)
|
||||
s_signals.append(s_signal)
|
||||
r.append(m_signal.eq(reduce(or_, s_signals)))
|
||||
else:
|
||||
raise TypeError
|
||||
return r
|
||||
|
||||
def __len__(self):
|
||||
return layout_len(self.layout)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"
|
||||
import warnings
|
||||
warnings.warn("instead of nmigen.compat.genlib.record, use amaranth.compat.genlib.record",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
|
|
@ -1,16 +1,7 @@
|
|||
from ..._utils import deprecated
|
||||
from ...lib.cdc import ResetSynchronizer as NativeResetSynchronizer
|
||||
from amaranth.compat.genlib.resetsync import *
|
||||
from amaranth.compat.genlib.resetsync import __all__
|
||||
|
||||
|
||||
__all__ = ["AsyncResetSynchronizer"]
|
||||
|
||||
|
||||
@deprecated("instead of `migen.genlib.resetsync.AsyncResetSynchronizer`, "
|
||||
"use `nmigen.lib.cdc.ResetSynchronizer`; note that ResetSynchronizer accepts "
|
||||
"a clock domain name as an argument, not a clock domain object")
|
||||
class CompatResetSynchronizer(NativeResetSynchronizer):
|
||||
def __init__(self, cd, async_reset):
|
||||
super().__init__(async_reset, domain=cd.name)
|
||||
|
||||
|
||||
AsyncResetSynchronizer = CompatResetSynchronizer
|
||||
import warnings
|
||||
warnings.warn("instead of nmigen.compat.genlib.resetsync, use amaranth.compat.genlib.resetsync",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
|
|
@ -1,58 +1,7 @@
|
|||
from amaranth.compat.genlib.roundrobin import *
|
||||
from amaranth.compat.genlib.roundrobin import __all__
|
||||
|
||||
|
||||
import warnings
|
||||
|
||||
from ..fhdl.structure import Signal, If, Case
|
||||
from ..fhdl.module import CompatModule
|
||||
|
||||
|
||||
__all__ = ["RoundRobin", "SP_WITHDRAW", "SP_CE"]
|
||||
|
||||
(SP_WITHDRAW, SP_CE) = range(2)
|
||||
|
||||
class CompatRoundRobin(CompatModule):
|
||||
def __init__(self, n, switch_policy=SP_WITHDRAW):
|
||||
self.request = Signal(n)
|
||||
self.grant = Signal(max=max(2, n))
|
||||
self.switch_policy = switch_policy
|
||||
if self.switch_policy == SP_CE:
|
||||
warnings.warn("instead of `migen.genlib.roundrobin.RoundRobin`, "
|
||||
"use `nmigen.lib.scheduler.RoundRobin`; note that RoundRobin does not "
|
||||
"require a policy anymore but to get the same behavior as SP_CE you"
|
||||
"should use an EnableInserter",
|
||||
DeprecationWarning, stacklevel=1)
|
||||
self.ce = Signal()
|
||||
else:
|
||||
warnings.warn("instead of `migen.genlib.roundrobin.RoundRobin`, "
|
||||
"use `nmigen.lib.scheduler.RoundRobin`; note that RoundRobin does not "
|
||||
"require a policy anymore",
|
||||
DeprecationWarning, stacklevel=1)
|
||||
|
||||
###
|
||||
|
||||
if n > 1:
|
||||
cases = {}
|
||||
for i in range(n):
|
||||
switch = []
|
||||
for j in reversed(range(i+1, i+n)):
|
||||
t = j % n
|
||||
switch = [
|
||||
If(self.request[t],
|
||||
self.grant.eq(t)
|
||||
).Else(
|
||||
*switch
|
||||
)
|
||||
]
|
||||
if self.switch_policy == SP_WITHDRAW:
|
||||
case = [If(~self.request[i], *switch)]
|
||||
else:
|
||||
case = switch
|
||||
cases[i] = case
|
||||
statement = Case(self.grant, cases)
|
||||
if self.switch_policy == SP_CE:
|
||||
statement = If(self.ce, statement)
|
||||
self.sync += statement
|
||||
else:
|
||||
self.comb += self.grant.eq(0)
|
||||
|
||||
|
||||
|
||||
RoundRobin = CompatRoundRobin
|
||||
warnings.warn("instead of nmigen.compat.genlib.roundrobin, use amaranth.compat.genlib.roundrobin",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue