Source code for hdlConvertorAst.to.basic_hdl_sim_model.expr

from hdlConvertorAst.hdlAst import HdlOpType, HdlValueId, HdlValueInt, \
    HdlOp
from hdlConvertorAst.py_ver_compatibility import is_str
from hdlConvertorAst.to.common import ToHdlCommon, ASSOCIATIVITY
from hdlConvertorAst.to.hdlUtils import iter_with_last, Indent


L = ASSOCIATIVITY.L_TO_R
R = ASSOCIATIVITY.R_TO_L


[docs]class ToBasicHdlSimModelExpr(ToHdlCommon): OP_PRECEDENCE = { # TO/DOWNTO becomes a call to slice # HdlOpType.DOWNTO: 1, # HdlOpType.TO: 1, # note that HdlExpressions in BasicHdlSimModel # do not use == but ._eq() HdlOpType.EQ: (11, L), HdlOpType.NE: (11, L), HdlOpType.GT: (11, L), HdlOpType.LT: (11, L), HdlOpType.GE: (11, L), HdlOpType.LE: (11, L), HdlOpType.IS: (11, L), HdlOpType.IS_NOT: (11, L), HdlOpType.OR: (10, L), HdlOpType.XOR: (10, L), HdlOpType.AND: (9, L), HdlOpType.SLL: (8, L), HdlOpType.SRL: (8, L), HdlOpType.ADD: (7, L), HdlOpType.SUB: (7, L), HdlOpType.DIV: (6, L), HdlOpType.MUL: (6, L), HdlOpType.MOD: (6, L), HdlOpType.NEG_LOG: (5, R), HdlOpType.NEG: (5, R), HdlOpType.MINUS_UNARY: (5, R), HdlOpType.POW: (4, R), HdlOpType.INDEX: (1, L), HdlOpType.RISING: (1, L), HdlOpType.FALLING: (1, L), # concat/ternary become a call to _concat, _ternary__val function # HdlOpType.CONCAT: 2, # HdlOpType.TERNARY: 2, # rising/faling as ._onRisingEdge(), ._onFallingEdge() HdlOpType.CALL: (1, L), # parametrization values are parameters of component class # constructor HdlOpType.PARAMETRIZATION: (1, L), HdlOpType.DOT: (1, L), } _unaryEventOps = { HdlOpType.RISING: "._onRisingEdge()", HdlOpType.FALLING: "._onFallingEdge()", } GENERIC_UNARY_OPS = { HdlOpType.NEG_LOG: "not ", HdlOpType.NEG: "~", HdlOpType.MINUS_UNARY: "-", } GENERIC_BIN_OPS = { HdlOpType.AND: " & ", HdlOpType.OR: " | ", HdlOpType.XOR: " ^ ", HdlOpType.EQ: ' == ', HdlOpType.NE: " != ", HdlOpType.IS: ' is ', HdlOpType.IS_NOT: " is not ", HdlOpType.MUL: " * ", HdlOpType.DIV: " // ", HdlOpType.POW: " ** ", HdlOpType.MOD: " % ", HdlOpType.SLL: " << ", HdlOpType.SRL: " >> ", } GENERIC_BIN_OPS.update(ToHdlCommon.GENERIC_BIN_OPS)
[docs] def visit_HdlValueInt(self, o): """ :type o: HdlValueInt """ w = self.out.write if o.bits is None: w(str(o.val)) else: if o.base is None: w(str(o.val)) else: b = o.base v = o.val if is_str(v): if set(v) == set('x'): v = None f = "{0}" elif b == 2: f = "0b{0}" elif b == 8: f = "0o{0}" elif b == 10: f = "{0}" elif b == 16: f = "0x{0}" else: raise NotImplementedError(b) else: if b == 2: f = "0b{0:b}" elif b == 8: f = "0o{0:o}" elif b == 10: f = "{0:d}" elif b == 16: f = "0x{0:x}" else: raise NotImplementedError(b) v = f.format(v) w(v)
[docs] def visit_iHdlExpr(self, o): """ :type o: iHdlExpr """ w = self.out.write if isinstance(o, HdlValueId): w(o.val) return elif is_str(o): w('"%s"' % o) return elif isinstance(o, HdlValueInt): self.visit_HdlValueInt(o) return elif isinstance(o, (list, tuple)): with_nl = len(o) > 3 w("(") for elem in o: self.visit_iHdlExpr(elem) if with_nl: w(", \n") else: w(", ") w(")") return elif isinstance(o, HdlOp): self.visit_HdlOp(o) return elif o is None: w("None") return elif isinstance(o, dict): w("{") with Indent(self.out): for last, (k, v) in iter_with_last(sorted(o.items(), key=lambda x: x[0])): self.visit_iHdlExpr(k) w(": ") self.visit_iHdlExpr(v) if not last: w(",\n") else: w("\n") w("}") return elif isinstance(o, float): w("%f" % o) return raise NotImplementedError(o.__class__, o)
[docs] def visit_HdlOp(self, o): """ :type op: HdlOp """ ops = o.ops op = o.fn w = self.out.write op_str = self._unaryEventOps.get(op, None) if op_str is not None: op0 = ops[0] w(op0.val) w(op_str) elif op == HdlOpType.MAP_ASSOCIATION: # kwargs, [todo]: dict constructor self._visit_operand(o.ops[0], 0, o, False, False) w("=") self._visit_operand(o.ops[1], 1, o, False, False) elif op == HdlOpType.TERNARY: # not that this is not a ternary in hdl epxression but in python wich is evaluated # during object construction, the hdl ternary is _ternary function c, o1, o2 = o.ops self._visit_operand(o1, 0, o, False, False) w(" if ") self._visit_operand(c, 0, o, False, False) w(" else ") self._visit_operand(o2, 0, o, False, False) else: return super(ToBasicHdlSimModelExpr, self).visit_HdlOp(o)