def visit_HdlModuleDef(self, a): """ :type a: HdlModuleDef """ e = a.dec assert e is not None, a self.visit_doc(e) w = self.out.write w("module ") w(e.name) gs = e.params if gs: w(" #(\n") with Indent(self.out): for last, g in iter_with_last(gs): self.visit_generic_declr(g) if last: w("\n") else: w(",\n") w(")") ps = e.ports if ps: w(" (\n") with Indent(self.out): for last, p in iter_with_last(ps): self.visit_port_declr(p) if last: w("\n") else: w(",\n") w(")") w(";\n") w = self.out.write with Indent(self.out): for o in a.objs: if isinstance(o, HdlIdDef): self.visit_HdlIdDef(o) w(";\n") elif isinstance(o, HdlCompInst): self.visit_HdlCompInst(o) w(";\n\n") elif isinstance(o, iHdlStatement): need_semi = self.visit_iHdlStatement(o) if need_semi: w(";\n") else: w("\n\n") elif isinstance(o, HdlFunctionDef): self.visit_HdlFunctionDef(o) w("\n\n") elif o is None: w(";\n") else: raise NotImplementedError(o) self.out.write("endmodule\n")
def visit_type_declr(self, t): """ :type t: HdlIdDef """ self.visit_doc(t) w = self.out.write w(t.name) w(" = ") val = t.value if isinstance(val, HdlEnumDef): w('define_Enum3t("') w(t.name) w('", [') for last, (k, v) in iter_with_last(val.values): assert v is None, v w('"%s"' % k) if not last: w(", ") w("])()\n") elif isinstance(val, HdlOp) and val.fn == HdlOpType.INDEX: # array type def. self.visit_iHdlExpr(val) w("\n") else: raise NotImplementedError()
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) 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")
def visit_HdlStmBlock(self, stm): """ :type stm: HdlStmBlock """ w = self.out.write for is_last, i in iter_with_last(stm.body): self.visit_iHdlStatement_in_statement(i) if not is_last: w("\n")
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")
def visit_HdlStmBlock(self, o): """ :type o: HdlStmBlock """ self.visit_doc(o) w = self.out.write for is_last, i in iter_with_last(o.body): self.visit_iHdlStatement(i) if not is_last: w(",\n")
def visit_HdlOp(self, o): """ :type o: HdlOp """ w = self.out.write op = o.fn if op == HdlOpType.CONCAT: w = self.out.write w("{") for is_last, (o_i, _o) in iter_with_last(enumerate(o.ops)): self._visit_operand(_o, o_i, o, False, True) if not is_last: w(", ") w("}") return elif op == HdlOpType.REPL_CONCAT: w = self.out.write w("{") self._visit_operand(o.ops[0], 0, o, True, False) w("{") for is_last, (o_i, _o) in iter_with_last(enumerate(o.ops[1:])): self._visit_operand(_o, o_i, o, False, True) if not is_last: w(", ") w("}}") return elif op == HdlOpType.TERNARY: cond, v0, v1 = o.ops self._visit_operand(cond, 0, o, True, False) w(" ? ") self._visit_operand(v0, 1, o, False, False) w(" : ") self._visit_operand(v1, 2, o, False, False) return elif op == HdlOpType.TYPE_OF: w("type(") self._visit_operand(o.ops[0], 0, o, False, True) w(")") return else: super(ToVerilog2005Expr, self).visit_HdlOp(o) return True
def visit_HdlStmProcess(self, proc): """ :type proc: HdlStmProcess """ self.visit_doc(proc) sens = proc.sensitivity body = proc.body w = self.out.write skip_body = False if sens is None: if isinstance(body, HdlStmWait): skip_body = True wait = body body = [] elif (isinstance(body, HdlStmBlock) and body.body and isinstance(body.body[0], HdlStmWait)): wait = body.body[0] body = body.body[1:] else: wait = None if wait is None: assert self.top_stm is proc assert isinstance(body, HdlStmBlock), body body = body.body wait = body[-1] assert isinstance(wait, HdlStmWait), wait assert len(wait.val) == 0 body = body[:-1] w("initial") else: if self.top_stm is proc: w("always ") w("#") assert len(wait.val) == 1 self.visit_iHdlExpr(wait.val[0]) _body = HdlStmBlock() _body.body = body body = _body else: if self.top_stm is proc: w("always ") w("@(") for last, item in iter_with_last(sens): self.visit_iHdlExpr(item) if not last: w(", ") w(")") # to prevent useless newline for empty always/time waits if skip_body: return True else: return self.visit_iHdlStatement_in_statement(body)
def visit_operator_call(self, o): """ :type operator: HdlOp """ self._visit_operand(o.ops[0], 0, o, False, False) w = self.out.write w("(") for is_last, (o_i, _o) in iter_with_last(enumerate(o.ops[1:])): self._visit_operand(_o, o_i, o, False, True) if not is_last: w(", ") w(")")
def visit_report(self, args): """ :type args: List[iHdlExpr] """ w = self.out.write w("REPORT ") for is_last, (prefix, a) in iter_with_last( zip(("", "SEVERITY "), args)): w(prefix) self.visit_iHdlExpr(a) if not is_last: w(" ")
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")
def visit_HdlFunctionDef(self, o): """ :type o: HdlFunctionDef """ self.visit_doc(o) w = self.out.write if o.is_task: w("task ") else: w("function ") if not o.is_static: w("automatic ") if not o.is_task: self.visit_type_first_part(o.return_t) self.visit_type_array_part(o.return_t) if o.is_virtual or o.is_operator: raise NotImplementedError(o) w(" ") w(o.name) ps = o.params if ps: w(" (\n") with Indent(self.out): for last, p in iter_with_last(ps): self.visit_port_declr(p) if last: w("\n") else: w(",\n") w(")") w(";\n") with Indent(self.out): for s in o.body: if isinstance(s, HdlIdDef): self.visit_HdlIdDef(s) w(";\n") elif isinstance(s, iHdlStatement): need_semi = self.visit_iHdlStatement(s) if need_semi: w(";\n") else: w("\n") else: self.visit_iHdlExpr(s) w(";\n") if o.is_task: w("endtask") else: w("endfunction")
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") w("END ") w(vhdl_obj_name) w(";\n")
def visit_HdlStmFor(self, o): """ :type o: HdlStmFor :return: True if requires ;\n after end """ self.visit_doc(o) w = self.out.write w("for (") if isinstance(o.init, HdlStmBlock): init_stms = o.init.body else: init_stms = [ o.init, ] for is_last, stm in iter_with_last(init_stms): self.visit_iHdlStatement(stm) if not is_last: w(", ") w("; ") self.visit_iHdlExpr(o.cond) w("; ") if isinstance(o.init, HdlStmBlock): step_stms = o.step.body else: step_stms = [ o.step, ] for is_last, stm in iter_with_last(step_stms): self.visit_iHdlStatement(stm) if not is_last: w(", ") w(")") return self.visit_iHdlStatement_in_statement(o.body)
def visit_doc(self, obj, line_comment_prefix): """ Format doc as line comments :type line_comment_prefix: str """ doc = obj.doc if doc is not None: doc = doc.split("\n") w = self.out.write for last, d in iter_with_last(doc): if last and d == "": break w(line_comment_prefix) w(d) w("\n")
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 raise NotImplementedError(o.__class__, o)
def visit_HdlStmProcess(self, o): """ :type proc: HdlStmProcess """ self.visit_doc(o) sens = o.sensitivity w = self.out.write if o.labels: w(o.labels[0]) w(": ") w("PROCESS") if sens: w("(") for last, item in iter_with_last(sens): self.visit_iHdlExpr(item) if not last: w(", ") w(")") w("\n") self.visit_HdlStmBlock(o.body, force_space_before=False, force_begin_end=True) w(" PROCESS;\n")
def visit_HdlStmProcess(self, proc): """ :type proc: HdlStmProcess """ w = self.out.write w("# sensitivity: ") for last, s in iter_with_last(proc.sensitivity): if isinstance(s, HdlOp): w(str(s.fn)) w(" ") self.visit_iHdlExpr(s.ops[0]) else: self.visit_iHdlExpr(s) if not last: w(", ") w("\n") w("def ") w(proc.labels[0]) w("(self):\n") body = proc.body with Indent(self.out): self.visit_iHdlStatement_in_statement(body) w("\n")
def visit_HdlStmAssign(self, o): """ :type o: HdlStmAssign :return: True if requires ;\n after end """ self.visit_doc(o) w = self.out.write if self.top_stm is o: w("assign ") self.visit_iHdlExpr(o.dst) w(" = ") else: self.visit_iHdlExpr(o.dst) if o.is_blocking: w(" = ") else: w(" <= ") if o.time_delay is not None: w("#") self.visit_iHdlExpr(o.time_delay) w(" ") if o.event_delay is not None: w("@") if len(o.event_delay) > 1: w("(") for is_last, e in iter_with_last(o.event_delay): self.visit_iHdlExpr(e) if not is_last: w(", ") if len(o.event_delay) > 1: w(")") w(" ") self.visit_iHdlExpr(o.src) return True
def visit_HdlOp(self, op): """ :type o: HdlOp """ w = self.out.write o = op.fn if o == HdlOpType.RISING: self._visit_operand(op.ops[0], 0, op, False, False) w(".pos()") elif o == HdlOpType.FALLING: self._visit_operand(op.ops[0], 0, op, False, False) w(".neg()") elif o == HdlOpType.PARAMETRIZATION: self._visit_operand(op.ops[0], 0, op, False, False) w("<") for last, _o in iter_with_last(op.ops[1:]): self.visit_iHdlExpr(_o) if not last: w(", ") w(">") else: ToHdlCommon.visit_HdlOp(self, op) return True
def visit_HdlModuleDef(self, mod_def): """ :type mod_def: HdlModuleDef """ mod_dec = mod_def.dec assert mod_dec is not None, mod_def w = self.out.write w(DEFAULT_IMPORTS) w("\n") types, variables, processes, components = \ ToBasicHdlSimModel.split_HdlModuleDefObjs(self, mod_def.objs) self.visit_doc(mod_dec) ToBasicHdlSimModel.visit_component_imports(self, components) w("SC_MODULE(") w(mod_dec.name) w(") {\n") with Indent(self.out): if mod_dec.params: raise NotImplementedError() for t in types: self.visit_type_declr(t) w(";\n") w('// ports\n') try: self._is_port = True for p in mod_dec.ports: self.visit_HdlIdDef(p) w(";\n") finally: self._is_port = False w("// component instances\n") for c in components: w(c.module_name.val) w(" ") w(c.name.val) w('();\n') w("// internal signals\n") for v in variables: self.visit_HdlIdDef(v) w(";\n") for p in processes: self.visit_iHdlStatement(p) # extra line to separate a process functions w("\n") w("SC_CTOR(") w(mod_dec.name) w(")") if components: w(": ") for last, c in iter_with_last(components): w(c.name.val) w('("') w(c.name.val) if last: w('")') else: w('"), ') w(" {\n") with Indent(self.out): for p in processes: if p.sensitivity: w("SC_METHOD(") w(p.labels[0]) w(");\n") w("sensitive") for s in p.sensitivity: w(" << ") self.visit_iHdlExpr(s) w(";\n") else: w(p.labels[0]) w("();\n") w("// connect ports\n") for c in components: for pm in c.port_map: w(c.name.val) w('.') assert isinstance(pm, HdlOp) and\ pm.fn == HdlOpType.MAP_ASSOCIATION, pm mod_port, connected_sig = pm.ops assert isinstance(mod_port, HdlValueId), mod_port self.visit_iHdlExpr(mod_port) assert isinstance(connected_sig, HdlValueId), connected_sig w("(") self.visit_iHdlExpr(connected_sig) w(");\n") w("}\n") w("};\n")
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: 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): w('(') for last, ev in iter_with_last(_t.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(")") elif isinstance(_t, HdlOp): assert _t.fn == HdlOpType.INDEX, _t.fn 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 isinstance(_t, HdlClassDef): assert _t.type == HdlClassType.STRUCT, _t.type w("RECORD\n") with Indent(self.out): for m in _t.members: self.visit_HdlIdDef(m) w("END RECORD") else: raise NotImplementedError(type(_t)) finally: self.in_typedef = orig_in_typedef elif t == HdlTypeSubtype: 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: w("CONSTANT ") elif latch: w("VARIABLE ") else: w("SIGNAL ") w(name) w(" : ") self.visit_type(t) v = var.value if v is not None: w(" := ") self.visit_iHdlExpr(v) w(end)
def visit_HdlModuleDef(self, mod_def): """ :type mod_def: HdlModuleDef """ mod_dec = mod_def.dec assert mod_dec is not None w = self.out.write if self.add_imports: w(DEFAULT_IMPORTS) w("\n") if self.module_path_prefix is None: self.add_imports = False types, variables, processes, components = self.split_HdlModuleDefObjs( mod_def.objs) self.visit_component_imports(components) self.visit_doc(mod_dec) w("class ") w(mod_dec.name) w("(BasicRtlSimModel):\n") assert not mod_dec.params, "generic should be already resolved for this format" with Indent(self.out): for t in types: self.visit_type_declr(t) w('def __init__(self, sim: "BasicRtlSimulator", name="') w(mod_dec.name) w('"):\n') with Indent(self.out): w('BasicRtlSimModel.__init__(self, sim, name=name)\n') w('# ports\n') for port in mod_dec.ports: self.visit_HdlIdDef(port) w("# internal signals\n") for v in variables: self.visit_HdlIdDef(v) w("# component instances\n") for c in components: w("self.") w(c.name.val) w(" = ") w(c.module_name.val) w('(sim, "') w(c.name.val) w('")\n') w("def _init_body(self):\n") with Indent(self.out): for c in components: for pm in c.port_map: w("connectSimPort(self, self.") w(c.name.val) w(', "') assert isinstance(pm, HdlOp) and\ pm.fn == HdlOpType.MAP_ASSOCIATION, pm mod_port, connected_sig = pm.ops assert isinstance(connected_sig, HdlValueId), connected_sig self.visit_iHdlExpr(connected_sig) w('", "') assert isinstance(mod_port, HdlValueId), mod_port self.visit_iHdlExpr(mod_port) w('")\n') w('self._interfaces = (\n') with Indent(self.out): for p in chain(mod_dec.ports, variables): if not p.is_const: w("self.io.") w(p.name) w(',\n') w(')\n') w('self._processes = (\n') with Indent(self.out): for p in processes: w("self.") try: w(p.labels[0]) except Exception: raise w(",\n") w(")\n") w('self._units = (') with Indent(self.out): for c in components: w("self.") w(c.name.val) w(",\n") w(")\n") for proc in processes: w("sensitivity(self.") w(proc.labels[0]) w(', ') for last, s in iter_with_last(proc.sensitivity): if isinstance(s, HdlOp): w("(") w(str(sensitivityByOp(s.fn))) w(", self.io.") self.visit_iHdlExpr(s.ops[0]) w(')') else: w("self.io.") self.visit_iHdlExpr(s) if not last: w(", ") w(")\n") w("self._outputs[self.") w(proc.labels[0]) w("] = (\n") outputs = self.stm_outputs[proc] with Indent(self.out): for outp in outputs: w("self.io.") assert isinstance(outp, HdlValueId) w(outp.val) w(",\n") w(")\n") w("for u in self._units:\n") w(" u._init_body()\n\n") for p in processes: self.visit_HdlStmProcess(p) # extra line to separate a process functions w("\n")
def visit_HdlModuleDef(self, mod_def): """ :type mod_def: HdlModuleDef """ mod_dec = mod_def.dec assert mod_dec is not None, mod_def w = self.out.write w(DEFAULT_IMPORTS) w("\n") types, variables, processes, components = \ ToBasicHdlSimModel.split_HdlModuleDefObjs(self, mod_def.objs) self.visit_doc(mod_dec) ToBasicHdlSimModel.visit_component_imports(self, components) w("class ") w(mod_dec.name) w("(Unit):\n") port_params_comp_names = [] with Indent(self.out): if mod_dec.params: w('def _config(self):\n') with Indent(self.out): try: self._is_param = True for p in mod_dec.params: self.visit_HdlIdDef(p) port_params_comp_names.append(p.name) finally: self._is_param = False for t in types: self.visit_type_declr(t) w('def _declr(self):\n') with Indent(self.out): w('# ports\n') try: self._is_port = True for p in mod_dec.ports: self.visit_HdlIdDef(p) port_params_comp_names.append(p.name) finally: self._is_port = False w("# component instances\n") for c in components: w("self.") w(c.name.val) w(" = ") w(c.module_name.val) w('()\n') port_params_comp_names.append(c.name.val) w("def _impl(self):\n") with Indent(self.out): w("# internal signals\n") if port_params_comp_names: # ports and params to locals for last, name in iter_with_last(port_params_comp_names): w(name) if not last: w(", ") w(" = \\\n") for last, name in iter_with_last(port_params_comp_names): w("self.") w(name) if not last: w(", ") w("\n") for v in variables: self.visit_HdlIdDef(v) for c in components: for pm in c.port_map: w("connectSimPort(self, self.") w(c.name.val) w(', "') assert isinstance(pm, HdlOp) and\ pm.fn == HdlOpType.MAP_ASSOCIATION, pm mod_port, connected_sig = pm.ops assert isinstance(connected_sig, HdlValueId), connected_sig self.visit_iHdlExpr(connected_sig) w('", "') assert isinstance(mod_port, HdlValueId), mod_port self.visit_iHdlExpr(mod_port) w('", ') p = mod_port.obj assert p is not None, ( "HdlValueId to module ports " "shoudl have been discovered before") d = p.direction assert d in (HdlDirection.IN, HdlDirection.OUT), d w(str(d == HdlDirection.IN)) w(')\n') for p in processes: self.visit_iHdlStatement(p) # extra line to separate a process functions w("\n")