def visit_HdlModuleDef(self, a): """ :type a: HdlModuleDef """ mod_dec = a.dec assert mod_dec is not None, a assert not mod_dec.objs, mod_dec self.visit_doc(mod_dec) w = self.out.write w("module ") w(mod_dec.name) gs = mod_dec.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 = mod_dec.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_HdlStmFor(self, o): """ :type o: HdlStmFor :return: True if requires ;\n after end """ self.visit_doc(o) w = self.out.write if o.in_preproc: w("generate ") 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.step, 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(")") need_semi = self.visit_iHdlStatement_in_statement(o.body) if o.in_preproc: if need_semi: w(";\n") else: w("\n") w("endgenerate") return False else: return need_semi
def visit_iHdlExpr(self, expr): w = self.out.write if expr is HdlAll: w("ALL") elif expr is HdlOthers: w("OTHERS") elif self.in_typedef and expr is None: w("<>") elif is_str(expr): self.visit_str(expr) elif isinstance(expr, list): with_nl = len(expr) > 3 if with_nl: w("(\n") else: w("(") with Indent(self.out): for is_last, elem in iter_with_last(expr): self.visit_iHdlExpr(elem) if not is_last: if with_nl: w(",\n") else: w(", ") w(")") else: ToHdlCommon.visit_iHdlExpr(self, expr)
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, HdlPhysicalDef): # I don't get what this is, TODO raise NotImplementedError() 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_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 o.trigger_constrain is not None: raise NotImplementedError() 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_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, 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_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")
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_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_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_assert(self, args): """ :type args: List[iHdlExpr] """ w = self.out.write w("ASSERT ") for is_last, (prefix, a) in iter_with_last( zip(("", "REPORT ", "SEVERITY "), args)): w(prefix) self.visit_iHdlExpr(a) if not is_last: w(" ")
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_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 ivars_to_local_vars(self, var_names): if var_names: w = self.out.write VAR_PER_LINE_LIMIT = self.VAR_PER_LINE_LIMIT # ports and params to locals for i, (last, name) in enumerate(iter_with_last(var_names)): w(name) if not last: w(", ") if i % VAR_PER_LINE_LIMIT == 0 and i > 0: # jump to new line to have reasonably long variable list w("\\\n") w(" = \\\n") for i, (last, name) in enumerate(iter_with_last(var_names)): w("self.") w(name) if not last: w(", ") if i % VAR_PER_LINE_LIMIT == 0 and i > 0: # jump to new line to have reasonably long variable list w("\\\n") 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 elif isinstance(o, float): w("%f" % o) return raise NotImplementedError(o.__class__, o)
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.replace('\r', '')) w("\n")
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(")")
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 ts = self.top_stm if ts is o or (ts is not None and ts.in_preproc): 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_HdlOp(self, o): """ :type o: HdlOp """ fn = o.ops[0] if fn == HdlValueId("assert"): self.visit_assert(o.ops[1:]) return elif fn == HdlValueId("report"): self.visit_report(o.ops[1:]) return w = self.out.write op = o.fn if op == HdlOpType.RISING: w("RISING_EDGE(") self.visit_iHdlExpr(o.ops[0]) w(")") elif op == HdlOpType.FALLING: w("FALLING_EDGE(") self.visit_iHdlExpr(o.ops[0]) w(")") elif op == HdlOpType.INDEX or op == HdlOpType.CALL: self._visit_operand(o.ops[0], 0, o, False, False) w("(") for isLast, (o_i, _o) in iter_with_last(enumerate(o.ops[1:])): self._visit_operand(_o, o_i + 1, o, False, True) if not isLast: w(", ") w(")") elif op == HdlOpType.TERNARY: has_3_ops = len(o.ops) == 3 if has_3_ops: cond, o0, o1 = o.ops else: cond, o0 = o.ops self._visit_operand(o0, 1, o, True, False) w(" WHEN ") self._visit_operand(cond, 0, o, True, False) if has_3_ops: if isinstance(o1, HdlOp) and o1.fn == HdlOpType.TERNARY: w(" ELSE\n") self.visit_iHdlExpr(o1) # must not have parenthesis else: w(" ELSE ") self._visit_operand(o1, 2, o, False, False) elif op == HdlOpType.APOSTROPHE: self._visit_operand(o.ops[0], 0, o, True, False) w("'") args = o.ops[1] if isinstance(args, list): self.visit_iHdlExpr(args) elif isinstance(args, HdlValueId): # normal attribute self.visit_iHdlExpr(args) else: w("(") self._visit_operand(args, 0, o, False, True) w(")") elif op == HdlOpType.ABS: w("ABS(") self.visit_iHdlExpr(o.ops[0]) w(")") elif op == HdlOpType.DEFINE_RESOLVER: assert self.in_typedef self.visit_iHdlExpr(o.ops[0]) w(" ") self.visit_iHdlExpr(o.ops[1]) else: return ToHdlCommon.visit_HdlOp(self, o)
def visit_HdlModuleDef(self, mod_def): """ :type mod_def: HdlModuleDef """ mod_dec = mod_def.dec assert mod_dec is not None, mod_def assert not mod_dec.objs, mod_dec w = self.out.write w(DEFAULT_IMPORTS) w("\n") split_HdlModuleDefObjs = method_as_function( ToBasicHdlSimModel.split_HdlModuleDefObjs) types, variables, processes, components = \ split_HdlModuleDefObjs(self, mod_def.objs) self.visit_doc(mod_dec) method_as_function(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 assert not mod_dec.objs, mod_dec w = self.out.write if self.add_imports: w(DEFAULT_IMPORTS) w("\n") if self.module_path_prefix is None: self.add_imports = False split_HdlModuleDefObjs = method_as_function(ToBasicHdlSimModel.split_HdlModuleDefObjs) types, variables, processes, components = \ split_HdlModuleDefObjs(self, mod_def.objs) method_as_function(ToBasicHdlSimModel.visit_component_imports)(self, components) w("class ") w(mod_dec.name) w("(Unit):\n") port_params_comp_names = [] with Indent(self.out): self.visit_doc(mod_dec, doc_string=True) 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 w("\n") w('def _declr(self):\n') with Indent(self.out): for t in types: self.visit_type_declr(t) 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: if c.param_map: w(c.name.val) w(" = ") w("self.") w(c.name.val) w(" = ") w(c.module_name.val) w('()\n') port_params_comp_names.append(c.name.val) for cp in c.param_map: mod_p, val = pop_port_or_param_map(cp) w(c.name.val) w(".") w(mod_p.val) w(" = ") self.visit_iHdlExpr(val) w("\n") w("\n") 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: mod_port, connected_sig = pop_port_or_param_map(pm) assert isinstance( connected_sig, HdlValueId), connected_sig p = mod_port.obj assert p is not None, ( "HdlValueId to module ports " "shoudl have been discovered before") d = p.direction assert d.name in (HdlDirection.IN.name, HdlDirection.OUT.name), d is_input = d.name == HdlDirection.IN.name if is_input: w(c.name.val) w(".") self.visit_iHdlExpr(mod_port) w("(") self.visit_iHdlExpr(connected_sig) w(")\n") else: self.visit_iHdlExpr(connected_sig) w("(") w(c.name.val) w(".") self.visit_iHdlExpr(mod_port) w(")\n") for p in processes: self.visit_iHdlStatement(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)
def _impl(self) -> None: _string_rom, strings_offset_and_size, max_chars_per_format, max_bcd_digits = self.build_string_rom( ) if self.DATA_WIDTH != 8: # it self.DATA_WIDTH != 1B we need to handle all possible alignments and shifts, precompute some strings # because number of string memory ports is limited etc. raise NotImplementedError() # instanciate bin_to_bcd if required if max_bcd_digits > 0: bin_to_bcd = BinToBcd() bin_to_bcd.INPUT_WIDTH = log2ceil(10**max_bcd_digits - 1) self.bin_to_bcd = bin_to_bcd # tuples (cond, input) to_bcd_inputs = [] string_rom = self._sig("string_rom", Bits(8)[len(_string_rom)], def_val=[int(c) for c in _string_rom]) char_i = self._reg("char_i", Bits(log2ceil(max_chars_per_format), signed=False), def_val=0) # create an iterator over all characters element_cnt = len(self.FORMAT) dout = self.data_out if element_cnt == 1: en = 1 f_i = 0 f = self.FORMAT[f_i] _, out_vld, out_last = self.connect_single_format_group( f_i, f, strings_offset_and_size, string_rom, char_i, to_bcd_inputs, en) char_i_rst = out_last else: main_st = self._reg("main_st", Bits(log2ceil(element_cnt), signed=False), def_val=0) char_i_rst = out_last = out_vld = BIT.from_py(0) main_st_fsm = Switch(main_st) for is_last_f, (f_i, f) in iter_with_last(enumerate(self.FORMAT)): en = main_st._eq(f_i) data_drive, in_vld, in_last = self.connect_single_format_group( f_i, f, strings_offset_and_size, string_rom, char_i, to_bcd_inputs, en) # build out vld from all input valids out_vld = out_vld | (en & in_vld) # keep only last of the last part out_last = en & in_last char_i_rst = char_i_rst | out_last main_st_fsm.Case( f_i, If(dout.ready & in_vld & in_last, main_st(0) if is_last_f else main_st(main_st + 1)), *data_drive) main_st_fsm.Default(main_st(None), dout.data(None)) dout.valid(out_vld) dout.last(out_last) If(dout.ready & out_vld, If(char_i_rst, char_i(0)).Else(char_i(char_i + 1))) if to_bcd_inputs: in_ = bin_to_bcd.din SwitchLogic( # actual value may be smaller, because bcd is shared among # multiple input formats [(c, in_.data(fitTo(v, in_.data, shrink=False))) for c, v in to_bcd_inputs], default=in_.data(None)) in_.vld(char_i._eq(0) & Or(*(c for c, _ in to_bcd_inputs))) propagateClkRstn(self)
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): 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) 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)