Beispiel #1
0
    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")
Beispiel #2
0
    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
Beispiel #3
0
 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)
Beispiel #4
0
 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()
Beispiel #5
0
    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")
Beispiel #6
0
 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")
Beispiel #7
0
 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")
Beispiel #8
0
 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")
Beispiel #9
0
    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")
Beispiel #10
0
 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")
Beispiel #11
0
    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)
Beispiel #12
0
 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
Beispiel #13
0
 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(" ")
Beispiel #14
0
 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(")")
Beispiel #15
0
 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")
Beispiel #16
0
    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")
Beispiel #17
0
 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")
Beispiel #18
0
    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)
Beispiel #19
0
    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")
Beispiel #20
0
    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(")")
Beispiel #21
0
 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")
Beispiel #22
0
    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
Beispiel #23
0
    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
Beispiel #24
0
    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)
Beispiel #25
0
    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")
Beispiel #26
0
    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")
Beispiel #27
0
    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)
Beispiel #28
0
    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)
Beispiel #29
0
    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")
Beispiel #30
0
    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)