hdl.xfrm: separate AST traversal from AST identity mapping.

This is useful because backends don't generally want or need AST
identity mapping (unlike all other transforms) and when adding a new
node, it results in confusing type errors.
This commit is contained in:
whitequark 2018-12-16 11:24:23 +00:00
parent 286a8009c8
commit 2be76fda3c
3 changed files with 94 additions and 26 deletions

View file

@ -6,7 +6,7 @@ from vcd.gtkw import GTKWSave
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"]
@ -44,7 +44,7 @@ class _State:
normalize = Const.normalize
class _RHSValueCompiler(ValueTransformer):
class _RHSValueCompiler(AbstractValueTransformer):
def __init__(self, sensitivity=None, mode="rhs"):
self.sensitivity = sensitivity
self.signal_mode = mode
@ -165,7 +165,7 @@ class _RHSValueCompiler(ValueTransformer):
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
@ -234,7 +234,7 @@ class _LHSValueCompiler(ValueTransformer):
return eval
class _StatementCompiler(StatementTransformer):
class _StatementCompiler(AbstractStatementTransformer):
def __init__(self):
self.sensitivity = ValueSet()
self.rrhs_compiler = _RHSValueCompiler(self.sensitivity, mode="rhs")

View file

@ -195,7 +195,7 @@ def src(src_loc):
return "{}:{}".format(file, line)
class _ValueTransformer(xfrm.ValueTransformer):
class _ValueTransformer(xfrm.AbstractValueTransformer):
operator_map = {
(1, "~"): "$not",
(1, "-"): "$neg",
@ -300,6 +300,12 @@ class _ValueTransformer(xfrm.ValueTransformer):
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()
@ -397,8 +403,8 @@ class _ValueTransformer(xfrm.ValueTransformer):
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])))
@ -406,6 +412,9 @@ class _ValueTransformer(xfrm.ValueTransformer):
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: