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_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_HdlStmCase(self, o): """ :type o: HdlStmCase """ self.visit_doc(o) w = self.out.write w("CASE ") self.visit_iHdlExpr(o.switch_on) w(" IS\n") with Indent(self.out): cases = o.cases for k, stms in cases: w("WHEN ") self.visit_iHdlExpr(k) w(" =>") is_block = self.visit_HdlStmBlock(stms, begin_end=False) if is_block: w("\n") defal = o.default if defal is not None: is_block = w("WHEN OTHERS =>") self.visit_HdlStmBlock(defal, begin_end=False) if is_block: w("\n") w("END CASE;\n")
def visit_HdlIdDef(self, var): """ :type var: HdlIdDef """ self.visit_doc(var) w = self.out.write if var.is_const: w("self.") w(var.name) w(" = ") self.visit_iHdlExpr(var.value) w("\n") else: w("self.io.") w(var.name) w(' = BasicRtlSimProxy(\n') with Indent(self.out): w('sim, self, "') w(var.name) w('",\n') self.visit_type(var.type) w(", ") if var.value is None: w("None)\n") else: self.visit_iHdlExpr(var.value) w(")\n")
def visit_HdlIdDef(self, var): """ :type var: HdlIdDef """ self.visit_doc(var) w = self.out.write if self._is_port or self._is_param: w("self.") w(var.name) if self._is_port: w(" = Signal(") self.visit_type(var.type) w(")") if var.direction == HdlDirection.OUT: w("._m()\n") else: w("\n") assert var.direction == HdlDirection.IN, var.direction elif self._is_param: raise NotImplementedError() else: # body signal w(' = self._sig(') with Indent(self.out): w('"') w(var.name) w('", ') self.visit_type(var.type) if var.value is None: w(")\n") else: w(", def_val=") self.visit_iHdlExpr(var.value) w(")\n")
def visit_HdlStmCase(self, o): """ :type o: HdlStmCase :return: True if requires ;\n after end """ self.visit_doc(o) w = self.out.write w("case(") self.visit_iHdlExpr(o.switch_on) w(")\n") with Indent(self.out): cases = o.cases for k, stms in cases: self.visit_iHdlExpr(k) w(":") need_semi = self.visit_iHdlStatement_in_statement(stms) if need_semi: w(";\n") else: w("\n") defal = o.default if defal is not None: w("default:") need_semi = self.visit_iHdlStatement_in_statement(defal) if need_semi: w(";\n") else: w("\n") w("endcase") return False
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_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) else: raise NotImplementedError(o) if in_def_section: w("BEGIN\n")
def visit_component_imports(self, components): w = self.out.write prefix = self.module_path_prefix if prefix is not None: for c in components: n = c.module_name with Indent(self.out): w('from %s.%s import %s\n' % (prefix, n, 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_HdlStmIf(self, stm): """ :type stm: HdlStmIf if cond: ... else: ... will become c, cVld = sim_eval_cond(cond) if not cVld: # ivalidate outputs elif c: ... else: ... """ w = self.out.write c = stm.cond ifTrue = stm.if_true ifFalse = stm.if_false w("if ") self.visit_iHdlExpr(c) w(":\n") with Indent(self.out): self.visit_iHdlStatement_in_statement(ifTrue) w("\n") for (c, _stm) in stm.elifs: w("elif ") self.visit_iHdlExpr(c) w(":\n") with Indent(self.out): self.visit_iHdlStatement_in_statement(_stm) w("\n") w("else:\n") with Indent(self.out): if ifFalse is None: w("pass") else: self.visit_iHdlStatement_in_statement(ifFalse)
def visit_HdlStmIf(self, o): """ :type stm: HdlStmIf if cond: ... else: ... will become c, cVld = sim_eval_cond(cond) if not cVld: # ivalidate outputs elif c: ... else: ... """ self.visit_doc(o) w = self.out.write w("If(") self.visit_iHdlExpr(o.cond) w(",\n") with Indent(self.out): self.visit_iHdlStatement(o.if_true) w("\n") w(")") for (c, _stm) in o.elifs: w(".Elif(") self.visit_iHdlExpr(c) w(",\n") with Indent(self.out): self.visit_iHdlStatement(_stm) w("\n") w(")") ifFalse = o.if_false if ifFalse is not None: w(".Else(\n") with Indent(self.out): self.visit_iHdlStatement(ifFalse) w("\n") w(")")
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_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")
def visit_HdlStmFor(self, o): """ :type o: HdlStmFor """ self.visit_doc(o) w = self.out.write w("FOR ") self.visit_iHdlExpr(o.params[0]) w(" IN ") self.visit_iHdlExpr(o.params[1]) w(" LOOP\n") with Indent(self.out): for b in o.body: self.visit_iHdlStatement(b) w("END FOR;\n")
def visit_HdlStmCase(self, o): """ :type o: HdlStmCase """ self.visit_doc(o) w = self.out.write w("Switch(") self.visit_iHdlExpr(o.switch_on) w(")") with Indent(self.out): for c, stm in o.cases: w("\\\n") w(".Case(") self.visit_iHdlExpr(c) w(",\n") with Indent(self.out): self.visit_iHdlStatement(stm) w(")") if o.default is not None: w("\\\n") w(".Default(\n") with Indent(self.out): self.visit_iHdlStatement(o.default) w(")")
def visit_iHdlStatement_in_statement(self, stm): """ Print statement which is body of other statement e.g. body of process, branch of if-then-else or case of case stememnt """ w = self.out.write if isinstance(stm, HdlStmBlock): if len(stm.body) == 1 and not stm.labels: stm = stm.body[0] else: w(" ") return self.visit_HdlStmBlock(stm) w("\n") with Indent(self.out): return self.visit_iHdlStatement(stm)
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_HdlStmAssign(self, o): """ :type o: HdlStmAssign """ w = self.out.write if o.time_delay is not None: raise NotImplementedError() if o.event_delay is not None: raise NotImplementedError() self.visit_iHdlExpr(o.dst) if o.is_blocking: w(" := ") else: w(" <= ") with Indent(self.out): self.visit_iHdlExpr(o.src) w(";\n")
def visit_HdlStmBlock(self, stms, force_space_before=True, begin_end=True, force_begin_end=False): """ :type stms: Union[List[iHdlStatement], iHdlStatement, iHdlExpr] :return: True if statements are wrapped in begin-end block """ w = self.out.write if isinstance(stms, HdlStmBlock): self.visit_doc(stms) must_have_begin_end = True stms = stms.body elif isinstance(stms, list): must_have_begin_end = len(stms) != 1 else: must_have_begin_end = False stms = [stms, ] must_have_begin_end |= force_begin_end non_declarative_seen = False with Indent(self.out): for s in stms: if isinstance(s, iHdlStatement): if not non_declarative_seen: non_declarative_seen = True with UnIndent(self.out): self._write_begin(begin_end, must_have_begin_end, force_space_before) self.visit_iHdlStatement(s) elif isinstance(s, HdlIdDef): self.visit_HdlIdDef(s) else: if not non_declarative_seen: non_declarative_seen = True with UnIndent(self.out): self._write_begin(begin_end, must_have_begin_end, force_space_before) self.visit_iHdlExpr(s) w(";\n") if not non_declarative_seen: self._write_begin(begin_end, must_have_begin_end, force_space_before) if begin_end and must_have_begin_end: w("END") return True return False
def visit_type_declr(self, var): """ :type var: HdlIdDef """ assert var.type == HdlTypeType self.visit_doc(var) w = self.out.write w("typedef ") t, arr_dims = collect_array_dims(var.value) with Indent(self.out): self.visit_iHdlExpr(t) w(" ") w(var.name) for d in arr_dims: w("[") self.visit_iHdlExpr(d) w("]") return True
def visit_HdlIdDef(self, var): """ :type var: HdlIdDef """ self.visit_doc(var) w = self.out.write t, arr_dims = collect_array_dims(var.type) self.visit_type(t) w(" ") w(var.name) for d in arr_dims: w("[") self.visit_iHdlExpr(d) w("]") if var.value is not None: w(" = ") with Indent(self.out): self.visit_iHdlExpr(var.value) return True
def visit_HdlStmBlock(self, o): """ :type o: HdlStmBlock """ self.visit_doc(o) w = self.out.write w("begin") if o.labels: w(": ") w(o.labels[0]) w("\n") with Indent(self.out): for s in o.body: need_semi = self.visit_iHdlStatement(s) if need_semi: w(";\n") else: w("\n") w("end") return False
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_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_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")
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_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)