Source code for hdlConvertorAst.to.vhdl.vhdl2008

from hdlConvertorAst.hdlAst import HdlDirection, iHdlStatement, \
    HdlIdDef, HdlModuleDec, HdlFunctionDef, HdlCompInst, \
    HdlTypeType, HdlOp, HdlOpType, HdlValueIdspace, HdlPhysicalDef, \
    HdlEnumDef, HdlTypeSubtype, HdlValueInt, HdlClassDef, HdlClassType, \
    HdlValueId
from hdlConvertorAst.to.hdlUtils import Indent, iter_with_last, UnIndent
from hdlConvertorAst.to.vhdl.stm import ToVhdl2008Stm


[docs]class ToVhdl2008(ToVhdl2008Stm): """ Convert hdlObject AST back to VHDL """ DIR2V = { HdlDirection.IN: "IN", HdlDirection.OUT: "OUT", HdlDirection.INOUT: "INOUT", }
[docs] def __init__(self, out_stream): ToVhdl2008Stm.__init__(self, out_stream) self.in_typedef = False
[docs] def visit_doc(self, obj): return super(ToVhdl2008, self).visit_doc(obj, "--")
[docs] def visit_direction(self, d): vd = self.DIR2V[d] self.out.write(vd)
[docs] def visit_main_obj(self, o): ToVhdl2008Stm.visit_main_obj(self, o) add_nl = isinstance(o, (HdlModuleDec, HdlModuleDec, HdlValueIdspace)) if add_nl: self.out.write("\n")
[docs] def visit_param_or_port_declr(self, o, is_param): """ :type p: HdlIdDef """ self.visit_doc(o) w = self.out.write w(o.name) w(" : ") if not is_param: d = o.direction if d != HdlDirection.INTERNAL: self.visit_direction(d) w(" ") self.visit_type(o.type) v = o.value if v is not None: w(" := ") self.visit_iHdlExpr(v)
[docs] def visit_HdlModuleDec(self, e, vhdl_obj_name="ENTITY"): """ :param e: Entity :type e: HdlModuleDec """ self.visit_doc(e) w = self.out.write w(vhdl_obj_name) w(" ") w(e.name) w(" IS\n") gs = e.params if gs: with Indent(self.out): w("GENERIC(\n") with Indent(self.out): for last, g in iter_with_last(gs): self.visit_param_or_port_declr(g, True) if last: w("\n") else: w(";\n") w(");\n") ps = e.ports if ps: with Indent(self.out): w("PORT(\n") with Indent(self.out): for last, p in iter_with_last(ps): self.visit_param_or_port_declr(p, False) if last: w("\n") else: w(";\n") w(");\n") di = e.objs if di: with Indent(self.out): for o in di: self.visit_iHdlObj(o) w("END ") w(vhdl_obj_name) w(";\n")
[docs] def visit_component(self, o): """ :type o: HdlModuleDec """ self.visit_HdlModuleDec(o, vhdl_obj_name="COMPONENT")
[docs] def visit_type(self, t): """ :type t: iHdlExpr """ self.visit_iHdlExpr(t)
[docs] def visit_map_item(self, item): self.visit_iHdlExpr(item)
[docs] def visit_map(self, map_): w = self.out.write with Indent(self.out): for last, m in iter_with_last(map_): self.visit_map_item(m) if last: w("\n") else: w(",\n")
[docs] def visit_HdlCompInst(self, c): """ :type c: HdlCompInst """ self.visit_doc(c) w = self.out.write w(c.name.val) w(": ") if not isinstance(c.module_name, HdlValueId): w("ENTITY ") self.visit_iHdlExpr(c.module_name) gms = c.param_map if gms: w(" GENERIC MAP(\n") self.visit_map(gms) w(")") pms = c.port_map if pms: w(" PORT MAP(\n") self.visit_map(pms) w(")") w(";")
[docs] def visit_body_items(self, objs): w = self.out.write in_def_section = True with Indent(self.out): for o in objs: if isinstance(o, HdlIdDef): assert in_def_section, o self.visit_HdlIdDef(o) continue elif isinstance(o, HdlModuleDec): assert in_def_section, o self.visit_component(o) continue elif isinstance(o, HdlFunctionDef): assert in_def_section, o self.visit_HdlFunctionDef(o) continue if in_def_section: with UnIndent(self.out): w("BEGIN\n") in_def_section = False if isinstance(o, HdlCompInst): self.visit_HdlCompInst(o) w("\n") elif isinstance(o, iHdlStatement): self.visit_iHdlStatement(o) elif isinstance(o, HdlOp) and o.fn == HdlOpType.CALL: self.visit_HdlOp(o) w(";\n") else: raise NotImplementedError(o) if in_def_section: w("BEGIN\n")
[docs] def visit_HdlModuleDef(self, o): """ :type o: HdlModuleDef """ w = self.out.write if o.dec is not None: self.visit_HdlModuleDec(o.dec) w("\n") self.visit_doc(o) w("ARCHITECTURE ") w(o.name) w(" OF ") w(o.module_name.val) w(" IS\n") self.visit_body_items(o.objs) self.out.write("END ARCHITECTURE;\n")
[docs] def visit_HdlIdDef(self, var, end=";\n"): """ :type var: HdlIdDef """ self.visit_doc(var) w = self.out.write name = var.name t = var.type if t == HdlTypeType: assert not var.is_shared orig_in_typedef = self.in_typedef try: self.in_typedef = True # typedef w("TYPE ") w(name) w(" IS ") _t = var.value if isinstance(_t, HdlEnumDef): self.visit_HdlEnumDef(_t) elif isinstance(_t, HdlOp): if _t.fn == HdlOpType.INDEX: w("ARRAY (") for last, i in iter_with_last(_t.ops[1:]): self.visit_iHdlExpr(i) if not last: w(", ") w(") OF ") self.visit_iHdlExpr(_t.ops[0]) elif _t.fn == HdlOpType.RANGE: w("RANGE ") assert len(_t.ops) == 1, _t.ops self.visit_iHdlExpr(_t.ops[0]) else: raise NotImplementedError(_t.fn) elif isinstance(_t, HdlClassDef): self.visit_HdlClassDef(_t) elif isinstance(_t, HdlPhysicalDef): self.visit_HdlPhysicalDef(_t) else: raise NotImplementedError(type(_t)) finally: self.in_typedef = orig_in_typedef elif t == HdlTypeSubtype: assert not var.is_shared orig_in_typedef = self.in_typedef try: self.in_typedef = True w("SUBTYPE ") w(name) w(" IS ") self.visit_iHdlExpr(var.value) finally: self.in_typedef = orig_in_typedef else: # signal/variable/port/generic if not self.in_typedef: latch = var.is_latched c = var.is_const if c: assert not var.is_shared w("CONSTANT ") elif latch: if var.is_shared: w("SHARED ") w("VARIABLE ") else: assert not var.is_shared w("SIGNAL ") w(name) w(" : ") self.visit_type(t) v = var.value if v is not None: w(" := ") self.visit_iHdlExpr(v) w(end)
[docs] def visit_HdlClassDef(self, o): """ :type o: HdlClassDef """ w = self.out.write assert o.type == HdlClassType.STRUCT, o.type w("RECORD\n") with Indent(self.out): for m in o.members: self.visit_HdlIdDef(m) w("END RECORD")
[docs] def visit_HdlPhysicalDef(self, o): """ :type o: HdlPhysicalDef """ w = self.out.write self.visit_HdlOp(o.range) w("\n") with Indent(self.out): w("UNITS\n") with Indent(self.out): for k, v in o.members: w(k) if v is not None: w(" = ") self.visit_HdlOp(v) w(";\n") w("END UNITS")
[docs] def visit_HdlEnumDef(self, o): """ :type o: HdlEnumDef """ w = self.out.write w('(') for last, ev in iter_with_last(o.values): k, v = ev if k is not None: w(k) else: assert isinstance(v, HdlValueInt) and v.base == 256, v self.visit_HdlValueInt(v) if not last: w(", ") w(")")
[docs] def visit_HdlFunctionDef(self, o): """ :type o: HdlFunctionDef """ self.visit_doc(o) w = self.out.write is_procedure = o.return_t is None if is_procedure: w("PROCEDURE ") else: w("FUNCTION ") w(o.name) if o.params: w(" (") with Indent(self.out): for is_last, par in iter_with_last(o.params): self.visit_HdlIdDef(par, end="") if not is_last: w(";\n") w(")") if not is_procedure: w(" RETURN ") self.visit_type(o.return_t) if o.is_declaration_only: w(";\n") else: w("\n") w("IS\n") self.visit_body_items(o.body) if is_procedure: w("END PROCEDURE;\n") else: w("END FUNCTION;\n")
[docs] def visit_HdlLibrary(self, o): """ :type o: HdlLibrary """ self.visit_doc(o) w = self.out.write w("LIBRARY ") w(o.name) w(";\n")
[docs] def visit_HdlImport(self, o): """ :type o: HdlImport """ self.visit_doc(o) w = self.out.write w("USE ") for last, p in iter_with_last(o.path): self.visit_iHdlExpr(p) if not last: w(".") w(";\n")
[docs] def visit_HdlValueIdspace(self, o): """ :type o: HdlValueIdspace """ self.visit_doc(o) w = self.out.write # TODO:: if o.declaration_only: w("PACKAGE ") w(o.name) w(" IS\n") with Indent(self.out): for _o in o.objs: self.visit_main_obj(_o) w("END PACKAGE;\n")
[docs] def _visit_HdlStmExitOrNext(self, o, stm_name): """ :type o: HdlOp :type stm_name: str :attention: next/exit statement is represented as a call of next/exit function and does not have a specific object, as it is expression it does not render the ending ; """ assert o.fn == HdlOpType.CALL and o.ops[0] == HdlValueId(stm_name), o w = self.out.write w(stm_name) if len(o.ops) == 1: pass elif len(o.ops) == 2: # label w(" ") self.visit_iHdlExpr(o.ops[1]) elif len(o.ops) == 3: # label, condition w(" ") _, label, cond = o.ops self.visit_iHdlExpr(label) w(" WHEN (") self.visit_iHdlExpr(cond) w(")") else: raise ValueError(o)
[docs] def visit_HdlOp(self, o): arg0 = o.ops[0] if o.fn == HdlOpType.CALL and isinstance(arg0, HdlValueId): if arg0.val == "EXIT": return self.visit_HdlStmExit(o) elif arg0.val == "NEXT": return self.visit_HdlStmNext(o) return ToVhdl2008Stm.visit_HdlOp(self, o)
[docs] def visit_HdlStmExit(self, o): """ :type o: HdlOp """ return self._visit_HdlStmExitOrNext(o, "EXIT")
[docs] def visit_HdlStmNext(self, o): """ :type o: HdlOp """ return self._visit_HdlStmExitOrNext(o, "NEXT")