amaranth/nmigen/compat/fhdl/structure.py

89 lines
3.2 KiB
Python
Raw Normal View History

from collections import OrderedDict
from ...tools import deprecated
2018-12-15 07:23:42 -07:00
from ...hdl import ast
2018-12-16 03:38:25 -07:00
from ...hdl.ast import (DUID, Value, Signal, Mux, Cat, Repl, Const, C, ClockSignal, ResetSignal,
Array, ArrayProxy as _ArrayProxy)
2018-12-15 07:23:42 -07:00
from ...hdl.cd import ClockDomain
__all__ = ["DUID", "wrap", "Mux", "Cat", "Replicate", "Constant", "C", "Signal", "ClockSignal",
"ResetSignal", "If", "Case", "Array", "ClockDomain",
"SPECIAL_INPUT", "SPECIAL_OUTPUT", "SPECIAL_INOUT"]
@deprecated("instead of `wrap`, use `Value.wrap`")
def wrap(v):
return Value.wrap(v)
@deprecated("instead of `Replicate`, use `Repl`")
def Replicate(v, n):
return Repl(v, n)
@deprecated("instead of `Constant`, use `Const`")
def Constant(value, bits_sign=None):
return Const(value, bits_sign)
class If(ast.Switch):
@deprecated("instead of `If(cond, ...)`, use `with m.If(cond): ...`")
def __init__(self, cond, *stmts):
cond = Value.wrap(cond).bool()
super().__init__(cond, {"1": ast.Statement.wrap(stmts)})
@deprecated("instead of `.Elif(cond, ...)`, use `with m.Elif(cond): ...`")
def Elif(self, cond, *stmts):
cond = Value.wrap(cond).bool()
self.cases = OrderedDict(("-" + k, v) for k, v in self.cases.items())
self.cases["1" + "-" * len(self.test)] = ast.Statement.wrap(stmts)
self.test = Cat(self.test, cond)
return self
@deprecated("instead of `.Else(...)`, use `with m.Else(): ...`")
def Else(self, *stmts):
self.cases["-" * len(self.test)] = ast.Statement.wrap(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 = []
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":
k = "-" * len(ast.Value.wrap(test))
else:
k = k.value
new_cases.append((k, v))
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
if isinstance(key, str) and key == "default":
key = "-" * len(self.test)
else:
key = "{:0{}b}".format(wrap(key).value, len(self.test))
stmts = self.cases[key]
del self.cases[key]
self.cases["-" * len(self.test)] = stmts
return self
(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)