from ..tools import flatten
from ..hdl.ast import *
-from ..hdl.xfrm import ValueTransformer, StatementTransformer
+from ..hdl.xfrm import AbstractValueTransformer, AbstractStatementTransformer
__all__ = ["Simulator", "Delay", "Tick", "Passive", "DeadlineError"]
normalize = Const.normalize
-class _RHSValueCompiler(ValueTransformer):
+class _RHSValueCompiler(AbstractValueTransformer):
def __init__(self, sensitivity=None, mode="rhs"):
self.sensitivity = sensitivity
self.signal_mode = mode
return lambda state: normalize(elems[index(state)](state), shape)
-class _LHSValueCompiler(ValueTransformer):
+class _LHSValueCompiler(AbstractValueTransformer):
def __init__(self, rhs_compiler):
self.rhs_compiler = rhs_compiler
return eval
-class _StatementCompiler(StatementTransformer):
+class _StatementCompiler(AbstractStatementTransformer):
def __init__(self):
self.sensitivity = ValueSet()
self.rrhs_compiler = _RHSValueCompiler(self.sensitivity, mode="rhs")
return "{}:{}".format(file, line)
-class _ValueTransformer(xfrm.ValueTransformer):
+class _ValueTransformer(xfrm.AbstractValueTransformer):
operator_map = {
(1, "~"): "$not",
(1, "-"): "$neg",
else:
return wire_curr
+ def on_ClockSignal(self, value):
+ raise NotImplementedError # :nocov:
+
+ def on_ResetSignal(self, value):
+ raise NotImplementedError # :nocov:
+
def on_Operator_unary(self, node):
arg, = node.operands
arg_bits, arg_sign = arg.shape()
else:
return "{} [{}:{}]".format(self(node.value), node.end - 1, node.start)
- # def on_Part(self, node):
- # return _Part(self(node.value), self(node.offset), node.width)
+ def on_Part(self, node):
+ raise NotImplementedError
def on_Cat(self, node):
return "{{ {} }}".format(" ".join(reversed([self(o) for o in node.operands])))
def on_Repl(self, node):
return "{{ {} }}".format(" ".join(self(node.value) for _ in range(node.count)))
+ def on_ArrayProxy(self, node):
+ raise NotImplementedError
+
def convert_fragment(builder, fragment, name, top):
with builder.module(name or "anonymous", attrs={"top": 1} if top else {}) as module:
+from abc import ABCMeta, abstractmethod
from collections import OrderedDict
from collections.abc import Iterable
from .ir import *
-__all__ = ["ValueTransformer", "StatementTransformer", "FragmentTransformer",
+__all__ = ["AbstractValueTransformer", "ValueTransformer",
+ "AbstractStatementTransformer", "StatementTransformer",
+ "FragmentTransformer",
"DomainRenamer", "DomainLowerer", "ResetInserter", "CEInserter"]
-class ValueTransformer:
+class AbstractValueTransformer(metaclass=ABCMeta):
+ @abstractmethod
def on_Const(self, value):
- return value
+ pass
+ @abstractmethod
def on_Signal(self, value):
- return value
+ pass
+ @abstractmethod
def on_ClockSignal(self, value):
- return value
+ pass
+ @abstractmethod
def on_ResetSignal(self, value):
- return value
+ pass
+ @abstractmethod
def on_Operator(self, value):
- return Operator(value.op, [self.on_value(o) for o in value.operands])
+ pass
+ @abstractmethod
def on_Slice(self, value):
- return Slice(self.on_value(value.value), value.start, value.end)
+ pass
+ @abstractmethod
def on_Part(self, value):
- return Part(self.on_value(value.value), self.on_value(value.offset), value.width)
+ pass
+ @abstractmethod
def on_Cat(self, value):
- return Cat(self.on_value(o) for o in value.operands)
+ pass
+ @abstractmethod
def on_Repl(self, value):
- return Repl(self.on_value(value.value), value.count)
+ pass
+ @abstractmethod
def on_ArrayProxy(self, value):
- return ArrayProxy([self.on_value(elem) for elem in value._iter_as_values()],
- self.on_value(value.index))
+ pass
def on_unknown_value(self, value):
raise TypeError("Cannot transform value '{!r}'".format(value)) # :nocov:
return self.on_value(value)
-class StatementTransformer:
- def on_value(self, value):
+class ValueTransformer(AbstractValueTransformer):
+ def on_Const(self, value):
+ return value
+
+ def on_Signal(self, value):
+ return value
+
+ def on_ClockSignal(self, value):
return value
+ def on_ResetSignal(self, value):
+ return value
+
+ def on_Operator(self, value):
+ return Operator(value.op, [self.on_value(o) for o in value.operands])
+
+ def on_Slice(self, value):
+ return Slice(self.on_value(value.value), value.start, value.end)
+
+ def on_Part(self, value):
+ return Part(self.on_value(value.value), self.on_value(value.offset), value.width)
+
+ def on_Cat(self, value):
+ return Cat(self.on_value(o) for o in value.operands)
+
+ 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))
+
+
+class AbstractStatementTransformer(metaclass=ABCMeta):
+ @abstractmethod
def on_Assign(self, stmt):
- return Assign(self.on_value(stmt.lhs), self.on_value(stmt.rhs))
+ pass
+ @abstractmethod
def on_Switch(self, stmt):
- cases = OrderedDict((k, self.on_statement(v)) for k, v in stmt.cases.items())
- return Switch(self.on_value(stmt.test), cases)
+ pass
+ @abstractmethod
def on_statements(self, stmt):
- return _StatementList(flatten(self.on_statement(stmt) for stmt in stmt))
+ pass
def on_unknown_statement(self, stmt):
raise TypeError("Cannot transform statement '{!r}'".format(stmt)) # :nocov:
return self.on_statement(value)
+class StatementTransformer(AbstractStatementTransformer):
+ def on_value(self, value):
+ return value
+
+ def on_Assign(self, stmt):
+ return Assign(self.on_value(stmt.lhs), self.on_value(stmt.rhs))
+
+ def on_Switch(self, stmt):
+ cases = OrderedDict((k, self.on_statement(v)) for k, v in stmt.cases.items())
+ return Switch(self.on_value(stmt.test), cases)
+
+ def on_statements(self, stmt):
+ return _StatementList(flatten(self.on_statement(stmt) for stmt in stmt))
+
+
class FragmentTransformer:
def map_subfragments(self, fragment, new_fragment):
for subfragment, name in fragment.subfragments: