hdl.ast: deprecate Repl and remove from AST; add Value.replicate.
This commit is contained in:
parent
b1cce87630
commit
d218273b9b
13 changed files with 83 additions and 95 deletions
|
|
@ -632,9 +632,6 @@ class _RHSValueCompiler(_ValueCompiler):
|
|||
}, src=_src(value.src_loc))
|
||||
return res
|
||||
|
||||
def on_Repl(self, value):
|
||||
return "{{ {} }}".format(" ".join(self(value.value) for _ in range(value.count)))
|
||||
|
||||
|
||||
class _LHSValueCompiler(_ValueCompiler):
|
||||
def on_Const(self, value):
|
||||
|
|
@ -695,9 +692,6 @@ class _LHSValueCompiler(_ValueCompiler):
|
|||
range(1 << len(value.offset))[:max_branches],
|
||||
value.src_loc)
|
||||
|
||||
def on_Repl(self, value):
|
||||
raise TypeError # :nocov:
|
||||
|
||||
|
||||
class _StatementCompiler(xfrm.StatementVisitor):
|
||||
def __init__(self, state, rhs_compiler, lhs_compiler):
|
||||
|
|
|
|||
|
|
@ -69,9 +69,9 @@ def Constant(value, bits_sign=None):
|
|||
return Const(value, bits_sign)
|
||||
|
||||
|
||||
@deprecated("instead of `Replicate`, use `Repl`")
|
||||
@deprecated("instead of `Replicate(v, n)`, use `v.replicate(n)`")
|
||||
def Replicate(v, n):
|
||||
return Repl(v, n)
|
||||
return v.replicate(n)
|
||||
|
||||
|
||||
@extend(Const)
|
||||
|
|
|
|||
|
|
@ -539,6 +539,29 @@ class Value(metaclass=ABCMeta):
|
|||
amount %= len(self)
|
||||
return Cat(self[amount:], self[:amount])
|
||||
|
||||
def replicate(self, count):
|
||||
"""Replication.
|
||||
|
||||
A ``Value`` is replicated (repeated) several times to be used
|
||||
on the RHS of assignments::
|
||||
|
||||
len(v.replicate(n)) == len(v) * n
|
||||
|
||||
Parameters
|
||||
----------
|
||||
count : int
|
||||
Number of replications.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Value, out
|
||||
Replicated value.
|
||||
"""
|
||||
if not isinstance(count, int) or count < 0:
|
||||
raise TypeError("Replication count must be a non-negative integer, not {!r}"
|
||||
.format(count))
|
||||
return Cat(self for _ in range(count))
|
||||
|
||||
def eq(self, value):
|
||||
"""Assignment.
|
||||
|
||||
|
|
@ -914,8 +937,9 @@ class Cat(Value):
|
|||
return "(cat {})".format(" ".join(map(repr, self.parts)))
|
||||
|
||||
|
||||
@final
|
||||
class Repl(Value):
|
||||
# TODO(amaranth-0.5): remove
|
||||
@deprecated("instead of `Repl(value, count)`, use `value.replicate(count)`")
|
||||
def Repl(value, count):
|
||||
"""Replicate a value
|
||||
|
||||
An input value is replicated (repeated) several times
|
||||
|
|
@ -932,31 +956,16 @@ class Repl(Value):
|
|||
|
||||
Returns
|
||||
-------
|
||||
Repl, out
|
||||
Value, out
|
||||
Replicated value.
|
||||
"""
|
||||
def __init__(self, value, count, *, src_loc_at=0):
|
||||
if not isinstance(count, int) or count < 0:
|
||||
raise TypeError("Replication count must be a non-negative integer, not {!r}"
|
||||
.format(count))
|
||||
if isinstance(value, int) and value not in [0, 1]:
|
||||
warnings.warn("Value argument of Repl() is a bare integer {} used in bit vector "
|
||||
"context; consider specifying explicit width using C({}, {}) instead"
|
||||
.format(value, value, bits_for(value)),
|
||||
SyntaxWarning, stacklevel=3)
|
||||
|
||||
super().__init__(src_loc_at=src_loc_at)
|
||||
if isinstance(value, int) and value not in [0, 1]:
|
||||
warnings.warn("Value argument of Repl() is a bare integer {} used in bit vector "
|
||||
"context; consider specifying explicit width using C({}, {}) instead"
|
||||
.format(value, value, bits_for(value)),
|
||||
SyntaxWarning, stacklevel=2 + src_loc_at)
|
||||
self.value = Value.cast(value)
|
||||
self.count = count
|
||||
|
||||
def shape(self):
|
||||
return Shape(len(self.value) * self.count)
|
||||
|
||||
def _rhs_signals(self):
|
||||
return self.value._rhs_signals()
|
||||
|
||||
def __repr__(self):
|
||||
return "(repl {!r} {})".format(self.value, self.count)
|
||||
return Value.cast(value).replicate(count)
|
||||
|
||||
|
||||
class _SignalMeta(ABCMeta):
|
||||
|
|
@ -1728,8 +1737,6 @@ class ValueKey:
|
|||
tuple(ValueKey(e) for e in self.value._iter_as_values())))
|
||||
elif isinstance(self.value, Sample):
|
||||
self._hash = hash((ValueKey(self.value.value), self.value.clocks, self.value.domain))
|
||||
elif isinstance(self.value, Repl):
|
||||
self._hash = hash((ValueKey(self.value.value), self.value.count))
|
||||
elif isinstance(self.value, Initial):
|
||||
self._hash = 0
|
||||
else: # :nocov:
|
||||
|
|
@ -1769,9 +1776,6 @@ class ValueKey:
|
|||
return (len(self.value.parts) == len(other.value.parts) and
|
||||
all(ValueKey(a) == ValueKey(b)
|
||||
for a, b in zip(self.value.parts, other.value.parts)))
|
||||
elif isinstance(self.value, Repl):
|
||||
return (ValueKey(self.value.value) == ValueKey(other.value.value) and
|
||||
self.value.count == other.value.count)
|
||||
elif isinstance(self.value, ArrayProxy):
|
||||
return (ValueKey(self.value.index) == ValueKey(other.value.index) and
|
||||
len(self.value.elems) == len(other.value.elems) and
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ class WritePort(Elaboratable):
|
|||
p_CLK_POLARITY=1,
|
||||
p_PRIORITY=0,
|
||||
i_CLK=ClockSignal(self.domain),
|
||||
i_EN=Cat(Repl(en_bit, self.granularity) for en_bit in self.en),
|
||||
i_EN=Cat(en_bit.replicate(self.granularity) for en_bit in self.en),
|
||||
i_ADDR=self.addr,
|
||||
i_DATA=self.data,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -62,10 +62,6 @@ class ValueVisitor(metaclass=ABCMeta):
|
|||
def on_Cat(self, value):
|
||||
pass # :nocov:
|
||||
|
||||
@abstractmethod
|
||||
def on_Repl(self, value):
|
||||
pass # :nocov:
|
||||
|
||||
@abstractmethod
|
||||
def on_ArrayProxy(self, value):
|
||||
pass # :nocov:
|
||||
|
|
@ -106,8 +102,6 @@ class ValueVisitor(metaclass=ABCMeta):
|
|||
new_value = self.on_Part(value)
|
||||
elif type(value) is Cat:
|
||||
new_value = self.on_Cat(value)
|
||||
elif type(value) is Repl:
|
||||
new_value = self.on_Repl(value)
|
||||
elif type(value) is ArrayProxy:
|
||||
new_value = self.on_ArrayProxy(value)
|
||||
elif type(value) is Sample:
|
||||
|
|
@ -156,9 +150,6 @@ class ValueTransformer(ValueVisitor):
|
|||
def on_Cat(self, value):
|
||||
return Cat(self.on_value(o) for o in value.parts)
|
||||
|
||||
def on_Repl(self, value):
|
||||
return Repl(self.on_value(value.value), value.count)
|
||||
|
||||
def on_ArrayProxy(self, value):
|
||||
return ArrayProxy([self.on_value(elem) for elem in value._iter_as_values()],
|
||||
self.on_value(value.index))
|
||||
|
|
@ -374,9 +365,6 @@ class DomainCollector(ValueVisitor, StatementVisitor):
|
|||
for o in value.parts:
|
||||
self.on_value(o)
|
||||
|
||||
def on_Repl(self, value):
|
||||
self.on_value(value.value)
|
||||
|
||||
def on_ArrayProxy(self, value):
|
||||
for elem in value._iter_as_values():
|
||||
self.on_value(elem)
|
||||
|
|
|
|||
|
|
@ -213,18 +213,6 @@ class _RHSValueCompiler(_ValueCompiler):
|
|||
return f"({' | '.join(gen_parts)})"
|
||||
return f"0"
|
||||
|
||||
def on_Repl(self, value):
|
||||
part_mask = (1 << len(value.value)) - 1
|
||||
gen_part = self.emitter.def_var("repl", f"{part_mask:#x} & {self(value.value)}")
|
||||
gen_parts = []
|
||||
offset = 0
|
||||
for _ in range(value.count):
|
||||
gen_parts.append(f"({gen_part} << {offset})")
|
||||
offset += len(value.value)
|
||||
if gen_parts:
|
||||
return f"({' | '.join(gen_parts)})"
|
||||
return f"0"
|
||||
|
||||
def on_ArrayProxy(self, value):
|
||||
index_mask = (1 << len(value.index)) - 1
|
||||
gen_index = self.emitter.def_var("rhs_index", f"{index_mask:#x} & {self(value.index)}")
|
||||
|
|
@ -325,9 +313,6 @@ class _LHSValueCompiler(_ValueCompiler):
|
|||
offset += len(part)
|
||||
return gen
|
||||
|
||||
def on_Repl(self, value):
|
||||
raise TypeError # :nocov:
|
||||
|
||||
def on_ArrayProxy(self, value):
|
||||
def gen(arg):
|
||||
index_mask = (1 << len(value.index)) - 1
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ class IntelPlatform(TemplatedPlatform):
|
|||
def _get_oereg(m, pin):
|
||||
# altiobuf_ requires an output enable signal for each pin, but pin.oe is 1 bit wide.
|
||||
if pin.xdr == 0:
|
||||
return Repl(pin.oe, pin.width)
|
||||
return pin.oe.replicate(pin.width)
|
||||
elif pin.xdr in (1, 2):
|
||||
oe_reg = Signal(pin.width, name="{}_oe_reg".format(pin.name))
|
||||
oe_reg.attrs["useioff"] = "1"
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ class LatticeECP5Platform(TemplatedPlatform):
|
|||
if "o" in pin.dir:
|
||||
o = pin_o
|
||||
if pin.dir in ("oe", "io"):
|
||||
t = Repl(~pin.oe, pin.width)
|
||||
t = (~pin.oe).replicate(pin.width)
|
||||
elif pin.xdr == 1:
|
||||
if "i" in pin.dir:
|
||||
get_ireg(pin.i_clk, i, pin_i)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue