Rename nMigen to Amaranth HDL.

This commit is contained in:
whitequark 2021-12-10 05:39:50 +00:00
parent 0b28a97ca0
commit 909a3b8be7
200 changed files with 14493 additions and 14451 deletions

View file

@ -0,0 +1,6 @@
from amaranth.compat.fhdl import *
import warnings
warnings.warn("instead of nmigen.compat.fhdl, use amaranth.compat.fhdl",
DeprecationWarning, stacklevel=2)

View file

@ -1,21 +1,7 @@
from ... import utils
from ...hdl import ast
from ..._utils import deprecated
from amaranth.compat.fhdl.bitcontainer import *
from amaranth.compat.fhdl.bitcontainer import __all__
__all__ = ["log2_int", "bits_for", "value_bits_sign"]
@deprecated("instead of `log2_int`, use `nmigen.utils.log2_int`")
def log2_int(n, need_pow2=True):
return utils.log2_int(n, need_pow2)
@deprecated("instead of `bits_for`, use `nmigen.utils.bits_for`")
def bits_for(n, require_sign_bit=False):
return utils.bits_for(n, require_sign_bit)
@deprecated("instead of `value_bits_sign(v)`, use `v.shape()`")
def value_bits_sign(v):
return tuple(ast.Value.cast(v).shape())
import warnings
warnings.warn("instead of nmigen.compat.fhdl.bitcontainer, use amaranth.compat.fhdl.bitcontainer",
DeprecationWarning, stacklevel=2)

View file

@ -1,35 +1,6 @@
from operator import itemgetter
from amaranth.compat.fhdl.conv_output import *
class ConvOutput:
def __init__(self):
self.main_source = ""
self.data_files = dict()
def set_main_source(self, src):
self.main_source = src
def add_data_file(self, filename_base, content):
filename = filename_base
i = 1
while filename in self.data_files:
parts = filename_base.split(".", maxsplit=1)
parts[0] += "_" + str(i)
filename = ".".join(parts)
i += 1
self.data_files[filename] = content
return filename
def __str__(self):
r = self.main_source + "\n"
for filename, content in sorted(self.data_files.items(),
key=itemgetter(0)):
r += filename + ":\n" + content
return r
def write(self, main_filename):
with open(main_filename, "w") as f:
f.write(self.main_source)
for filename, content in self.data_files.items():
with open(filename, "w") as f:
f.write(content)
import warnings
warnings.warn("instead of nmigen.compat.fhdl.conv_output, use amaranth.compat.fhdl.conv_output",
DeprecationWarning, stacklevel=2)

View file

@ -1,55 +1,7 @@
from ...hdl.ast import *
from ...hdl.xfrm import ResetInserter as NativeResetInserter
from ...hdl.xfrm import EnableInserter as NativeEnableInserter
from ...hdl.xfrm import DomainRenamer as NativeDomainRenamer
from ..._utils import deprecated
from amaranth.compat.fhdl.decorators import *
from amaranth.compat.fhdl.decorators import __all__
__all__ = ["ResetInserter", "CEInserter", "ClockDomainsRenamer"]
class _CompatControlInserter:
_control_name = None
_native_inserter = None
def __init__(self, clock_domains=None):
self.clock_domains = clock_domains
def __call__(self, module):
if self.clock_domains is None:
signals = {self._control_name: ("sync", Signal(name=self._control_name))}
else:
def name(cd):
return self._control_name + "_" + cd
signals = {name(cd): (cd, Signal(name=name(cd))) for cd in self.clock_domains}
for name, (cd, signal) in signals.items():
setattr(module, name, signal)
return self._native_inserter(dict(signals.values()))(module)
@deprecated("instead of `migen.fhdl.decorators.ResetInserter`, "
"use `nmigen.hdl.xfrm.ResetInserter`; note that nMigen ResetInserter accepts "
"a dict of reset signals (or a single reset signal) as an argument, not "
"a set of clock domain names (or a single clock domain name)")
class CompatResetInserter(_CompatControlInserter):
_control_name = "reset"
_native_inserter = NativeResetInserter
@deprecated("instead of `migen.fhdl.decorators.CEInserter`, "
"use `nmigen.hdl.xfrm.EnableInserter`; note that nMigen EnableInserter accepts "
"a dict of enable signals (or a single enable signal) as an argument, not "
"a set of clock domain names (or a single clock domain name)")
class CompatCEInserter(_CompatControlInserter):
_control_name = "ce"
_native_inserter = NativeEnableInserter
class CompatClockDomainsRenamer(NativeDomainRenamer):
def __init__(self, cd_remapping):
super().__init__(cd_remapping)
ResetInserter = CompatResetInserter
CEInserter = CompatCEInserter
ClockDomainsRenamer = CompatClockDomainsRenamer
import warnings
warnings.warn("instead of nmigen.compat.fhdl.decorators, use amaranth.compat.fhdl.decorators",
DeprecationWarning, stacklevel=2)

View file

@ -1,163 +1,7 @@
from collections.abc import Iterable
from ..._utils import flatten, deprecated
from ...hdl import dsl, ir
from amaranth.compat.fhdl.module import *
from amaranth.compat.fhdl.module import __all__
__all__ = ["Module", "FinalizeError"]
def _flat_list(e):
if isinstance(e, Iterable):
return list(flatten(e))
else:
return [e]
class CompatFinalizeError(Exception):
pass
FinalizeError = CompatFinalizeError
class _CompatModuleProxy:
def __init__(self, cm):
object.__setattr__(self, "_cm", cm)
class _CompatModuleComb(_CompatModuleProxy):
@deprecated("instead of `self.comb +=`, use `m.d.comb +=`")
def __iadd__(self, assigns):
self._cm._module._add_statement(assigns, domain=None, depth=0, compat_mode=True)
return self
class _CompatModuleSyncCD:
def __init__(self, cm, cd):
self._cm = cm
self._cd = cd
@deprecated("instead of `self.sync.<domain> +=`, use `m.d.<domain> +=`")
def __iadd__(self, assigns):
self._cm._module._add_statement(assigns, domain=self._cd, depth=0, compat_mode=True)
return self
class _CompatModuleSync(_CompatModuleProxy):
@deprecated("instead of `self.sync +=`, use `m.d.sync +=`")
def __iadd__(self, assigns):
self._cm._module._add_statement(assigns, domain="sync", depth=0, compat_mode=True)
return self
def __getattr__(self, name):
return _CompatModuleSyncCD(self._cm, name)
def __setattr__(self, name, value):
if not isinstance(value, _CompatModuleSyncCD):
raise AttributeError("Attempted to assign sync property - use += instead")
class _CompatModuleSpecials(_CompatModuleProxy):
@deprecated("instead of `self.specials.<name> =`, use `m.submodules.<name> =`")
def __setattr__(self, name, value):
self._cm._submodules.append((name, value))
setattr(self._cm, name, value)
@deprecated("instead of `self.specials +=`, use `m.submodules +=`")
def __iadd__(self, other):
self._cm._submodules += [(None, e) for e in _flat_list(other)]
return self
class _CompatModuleSubmodules(_CompatModuleProxy):
@deprecated("instead of `self.submodules.<name> =`, use `m.submodules.<name> =`")
def __setattr__(self, name, value):
self._cm._submodules.append((name, value))
setattr(self._cm, name, value)
@deprecated("instead of `self.submodules +=`, use `m.submodules +=`")
def __iadd__(self, other):
self._cm._submodules += [(None, e) for e in _flat_list(other)]
return self
class _CompatModuleClockDomains(_CompatModuleProxy):
@deprecated("instead of `self.clock_domains.<name> =`, use `m.domains.<name> =`")
def __setattr__(self, name, value):
self.__iadd__(value)
setattr(self._cm, name, value)
@deprecated("instead of `self.clock_domains +=`, use `m.domains +=`")
def __iadd__(self, other):
self._cm._module.domains += _flat_list(other)
return self
class CompatModule(ir.Elaboratable):
_MustUse__silence = True
# Actually returns another nMigen Elaboratable (nmigen.dsl.Module), not a Fragment.
def get_fragment(self):
assert not self.get_fragment_called
self.get_fragment_called = True
self.finalize()
return self._module
def elaborate(self, platform):
if not self.get_fragment_called:
self.get_fragment()
return self._module
def __getattr__(self, name):
if name == "comb":
return _CompatModuleComb(self)
elif name == "sync":
return _CompatModuleSync(self)
elif name == "specials":
return _CompatModuleSpecials(self)
elif name == "submodules":
return _CompatModuleSubmodules(self)
elif name == "clock_domains":
return _CompatModuleClockDomains(self)
elif name == "finalized":
self.finalized = False
return self.finalized
elif name == "_module":
self._module = dsl.Module()
return self._module
elif name == "_submodules":
self._submodules = []
return self._submodules
elif name == "_clock_domains":
self._clock_domains = []
return self._clock_domains
elif name == "get_fragment_called":
self.get_fragment_called = False
return self.get_fragment_called
else:
raise AttributeError("'{}' object has no attribute '{}'"
.format(type(self).__name__, name))
def finalize(self, *args, **kwargs):
def finalize_submodules():
for name, submodule in self._submodules:
if not hasattr(submodule, "finalize"):
continue
if submodule.finalized:
continue
submodule.finalize(*args, **kwargs)
if not self.finalized:
self.finalized = True
finalize_submodules()
self.do_finalize(*args, **kwargs)
finalize_submodules()
for name, submodule in self._submodules:
self._module._add_submodule(submodule, name)
def do_finalize(self):
pass
Module = CompatModule
import warnings
warnings.warn("instead of nmigen.compat.fhdl.module, use amaranth.compat.fhdl.module",
DeprecationWarning, stacklevel=2)

View file

@ -1,145 +1,7 @@
from amaranth.compat.fhdl.specials import *
from amaranth.compat.fhdl.specials import __all__
import warnings
from ..._utils import deprecated, extend
from ...hdl.ast import *
from ...hdl.ir import Elaboratable
from ...hdl.mem import Memory as NativeMemory
from ...hdl.ir import Fragment, Instance
from ...hdl.dsl import Module
from .module import Module as CompatModule
from .structure import Signal
from ...lib.io import Pin
__all__ = ["TSTriple", "Instance", "Memory", "READ_FIRST", "WRITE_FIRST", "NO_CHANGE"]
class TSTriple:
def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0, reset_i=0,
name=None):
self.o = Signal(bits_sign, min=min, max=max, reset=reset_o,
name=None if name is None else name + "_o")
self.oe = Signal(reset=reset_oe,
name=None if name is None else name + "_oe")
self.i = Signal(bits_sign, min=min, max=max, reset=reset_i,
name=None if name is None else name + "_i")
def __len__(self):
return len(self.o)
def get_tristate(self, io):
return Tristate(io, self.o, self.oe, self.i)
class Tristate(Elaboratable):
def __init__(self, target, o, oe, i=None):
self.target = target
self.o = o
self.oe = oe
self.i = i if i is not None else None
def elaborate(self, platform):
if self.i is None:
pin = Pin(len(self.target), dir="oe")
pin.o = self.o
pin.oe = self.oe
return platform.get_tristate(pin, self.target, attrs={}, invert=None)
else:
pin = Pin(len(self.target), dir="io")
pin.o = self.o
pin.oe = self.oe
pin.i = self.i
return platform.get_input_output(pin, self.target, attrs={}, invert=None)
m = Module()
if self.i is not None:
m.d.comb += self.i.eq(self.target)
m.submodules += Instance("$tribuf",
p_WIDTH=len(self.target),
i_EN=self.oe,
i_A=self.o,
o_Y=self.target,
)
f = m.elaborate(platform)
f.flatten = True
return f
(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
class _MemoryPort(CompatModule):
def __init__(self, adr, dat_r, we=None, dat_w=None, async_read=False, re=None,
we_granularity=0, mode=WRITE_FIRST, clock_domain="sync"):
self.adr = adr
self.dat_r = dat_r
self.we = we
self.dat_w = dat_w
self.async_read = async_read
self.re = re
self.we_granularity = we_granularity
self.mode = mode
self.clock = ClockSignal(clock_domain)
@extend(NativeMemory)
@deprecated("it is not necessary or permitted to add Memory as a special or submodule")
def elaborate(self, platform):
return Fragment()
class CompatMemory(NativeMemory, Elaboratable):
def __init__(self, width, depth, init=None, name=None):
super().__init__(width=width, depth=depth, init=init, name=name)
@deprecated("instead of `get_port()`, use `read_port()` and `write_port()`")
def get_port(self, write_capable=False, async_read=False, has_re=False, we_granularity=0,
mode=WRITE_FIRST, clock_domain="sync"):
if we_granularity >= self.width:
warnings.warn("do not specify `we_granularity` greater than memory width, as it "
"is a hard error in non-compatibility mode",
DeprecationWarning, stacklevel=1)
we_granularity = 0
if we_granularity == 0:
warnings.warn("instead of `we_granularity=0`, use `we_granularity=None` or avoid "
"specifying it at all, as it is a hard error in non-compatibility mode",
DeprecationWarning, stacklevel=1)
we_granularity = None
assert mode != NO_CHANGE
rdport = self.read_port(domain="comb" if async_read else clock_domain,
transparent=mode == WRITE_FIRST)
rdport.addr.name = "{}_addr".format(self.name)
adr = rdport.addr
dat_r = rdport.data
if write_capable:
wrport = self.write_port(domain=clock_domain, granularity=we_granularity)
wrport.addr = rdport.addr
we = wrport.en
dat_w = wrport.data
else:
we = None
dat_w = None
if has_re:
if mode == READ_FIRST:
re = rdport.en
else:
warnings.warn("the combination of `has_re=True` and `mode=WRITE_FIRST` has "
"surprising behavior: keeping `re` low would merely latch "
"the address, while the data will change with changing memory "
"contents; avoid using `re` with transparent ports as it is a hard "
"error in non-compatibility mode",
DeprecationWarning, stacklevel=1)
re = Signal()
else:
re = None
mp = _MemoryPort(adr, dat_r, we, dat_w,
async_read, re, we_granularity, mode,
clock_domain)
mp.submodules.rdport = rdport
if write_capable:
mp.submodules.wrport = wrport
return mp
Memory = CompatMemory
warnings.warn("instead of nmigen.compat.fhdl.specials, use amaranth.compat.fhdl.specials",
DeprecationWarning, stacklevel=2)

View file

@ -1,185 +1,7 @@
import builtins
from amaranth.compat.fhdl.structure import *
from amaranth.compat.fhdl.structure import __all__
import warnings
from collections import OrderedDict
from ...utils import bits_for
from ..._utils import deprecated, extend
from ...hdl import ast
from ...hdl.ast import (DUID,
Shape, signed, unsigned,
Value, Const, C, Mux, Slice as _Slice, Part, Cat, Repl,
Signal as NativeSignal,
ClockSignal, ResetSignal,
Array, ArrayProxy as _ArrayProxy)
from ...hdl.cd import ClockDomain
__all__ = ["DUID", "wrap", "Mux", "Cat", "Replicate", "Constant", "C", "Signal", "ClockSignal",
"ResetSignal", "If", "Case", "Array", "ClockDomain"]
@deprecated("instead of `wrap`, use `Value.cast`")
def wrap(v):
return Value.cast(v)
class CompatSignal(NativeSignal):
def __init__(self, bits_sign=None, name=None, variable=False, reset=0,
reset_less=False, name_override=None, min=None, max=None,
related=None, attr=None, src_loc_at=0, **kwargs):
if min is not None or max is not None:
warnings.warn("instead of `Signal(min={min}, max={max})`, "
"use `Signal(range({min}, {max}))`"
.format(min=min or 0, max=max or 2),
DeprecationWarning, stacklevel=2 + src_loc_at)
if bits_sign is None:
if min is None:
min = 0
if max is None:
max = 2
max -= 1 # make both bounds inclusive
if min > max:
raise ValueError("Lower bound {} should be less or equal to higher bound {}"
.format(min, max + 1))
sign = min < 0 or max < 0
if min == max:
bits = 0
else:
bits = builtins.max(bits_for(min, sign), bits_for(max, sign))
shape = signed(bits) if sign else unsigned(bits)
else:
if not (min is None and max is None):
raise ValueError("Only one of bits/signedness or bounds may be specified")
shape = bits_sign
super().__init__(shape=shape, name=name_override or name,
reset=reset, reset_less=reset_less,
attrs=attr, src_loc_at=1 + src_loc_at, **kwargs)
Signal = CompatSignal
@deprecated("instead of `Constant`, use `Const`")
def Constant(value, bits_sign=None):
return Const(value, bits_sign)
@deprecated("instead of `Replicate`, use `Repl`")
def Replicate(v, n):
return Repl(v, n)
@extend(Const)
@property
@deprecated("instead of `.nbits`, use `.width`")
def nbits(self):
return self.width
@extend(NativeSignal)
@property
@deprecated("instead of `.nbits`, use `.width`")
def nbits(self):
return self.width
@extend(NativeSignal)
@NativeSignal.nbits.setter
@deprecated("instead of `.nbits = x`, use `.width = x`")
def nbits(self, value):
self.width = value
@extend(NativeSignal)
@deprecated("instead of `.part`, use `.bit_select`")
def part(self, offset, width):
return Part(self, offset, width, src_loc_at=2)
@extend(Cat)
@property
@deprecated("instead of `.l`, use `.parts`")
def l(self):
return self.parts
@extend(ast.Operator)
@property
@deprecated("instead of `.op`, use `.operator`")
def op(self):
return self.operator
@extend(_ArrayProxy)
@property
@deprecated("instead `_ArrayProxy.choices`, use `ArrayProxy.elems`")
def choices(self):
return self.elems
class If(ast.Switch):
@deprecated("instead of `If(cond, ...)`, use `with m.If(cond): ...`")
def __init__(self, cond, *stmts):
cond = Value.cast(cond)
if len(cond) != 1:
cond = cond.bool()
super().__init__(cond, {("1",): ast.Statement.cast(stmts)})
@deprecated("instead of `.Elif(cond, ...)`, use `with m.Elif(cond): ...`")
def Elif(self, cond, *stmts):
cond = Value.cast(cond)
if len(cond) != 1:
cond = cond.bool()
self.cases = OrderedDict((("-" + k,), v) for (k,), v in self.cases.items())
self.cases[("1" + "-" * len(self.test),)] = ast.Statement.cast(stmts)
self.test = Cat(self.test, cond)
return self
@deprecated("instead of `.Else(...)`, use `with m.Else(): ...`")
def Else(self, *stmts):
self.cases[()] = ast.Statement.cast(stmts)
return self
class Case(ast.Switch):
@deprecated("instead of `Case(test, { value: stmts })`, use `with m.Switch(test):` and "
"`with m.Case(value): stmts`; instead of `\"default\": stmts`, use "
"`with m.Case(): stmts`")
def __init__(self, test, cases):
new_cases = []
default = None
for k, v in cases.items():
if isinstance(k, (bool, int)):
k = Const(k)
if (not isinstance(k, Const)
and not (isinstance(k, str) and k == "default")):
raise TypeError("Case object is not a Migen constant")
if isinstance(k, str) and k == "default":
default = v
continue
else:
k = k.value
new_cases.append((k, v))
if default is not None:
new_cases.append((None, default))
super().__init__(test, OrderedDict(new_cases))
@deprecated("instead of `Case(...).makedefault()`, use an explicit default case: "
"`with m.Case(): ...`")
def makedefault(self, key=None):
if key is None:
for choice in self.cases.keys():
if (key is None
or (isinstance(choice, str) and choice == "default")
or choice > key):
key = choice
elif isinstance(key, str) and key == "default":
key = ()
else:
key = ("{:0{}b}".format(ast.Value.cast(key).value, len(self.test)),)
stmts = self.cases[key]
del self.cases[key]
self.cases[()] = stmts
return self
warnings.warn("instead of nmigen.compat.fhdl.structure, use amaranth.compat.fhdl.structure",
DeprecationWarning, stacklevel=2)

View file

@ -1,35 +1,6 @@
from amaranth.compat.fhdl.verilog import *
import warnings
from ...hdl.ir import Fragment
from ...hdl.cd import ClockDomain
from ...back import verilog
from .conv_output import ConvOutput
from .module import Module
def convert(fi, ios=None, name="top", special_overrides=dict(),
attr_translate=None, create_clock_domains=True,
display_run=False):
if display_run:
warnings.warn("`display_run=True` support has been removed",
DeprecationWarning, stacklevel=1)
if special_overrides:
warnings.warn("`special_overrides` support as well as `Special` has been removed",
DeprecationWarning, stacklevel=1)
# TODO: attr_translate
if isinstance(fi, Module):
fi = fi.get_fragment()
def missing_domain(name):
if create_clock_domains:
return ClockDomain(name)
v_output = verilog.convert(
elaboratable=fi,
name=name,
ports=ios or (),
missing_domain=missing_domain
)
output = ConvOutput()
output.set_main_source(v_output)
return output
warnings.warn("instead of nmigen.compat.fhdl.verilog, use amaranth.compat.fhdl.verilog",
DeprecationWarning, stacklevel=2)