示例#1
0
class ClassNodeVHDL(NodeVHDL):
    def __init__(self, red_node, parent=None):
        super().__init__(red_node, parent)

        # todo: remove me after refactorings
        try:
            self.data = VHDLModule('-', convert_obj)
        except AttributeError:
            self.data = None
        # collect multiline comment
        self.multiline_comment = ''
        if len(self.value) and isinstance(self.value[0], StringNodeVHDL):
            self.multiline_comment = str(self.value[0])
            del self.value[0]

    def get_function(self, name):
        f = [x for x in self.value if str(x.name) == name]
        assert len(f)
        return f[0]

    def build_imports(self):
        template = textwrap.dedent("""\
            library ieee;
                use ieee.std_logic_1164.all;
                use ieee.numeric_std.all;
                use ieee.fixed_float_types.all;
                use ieee.fixed_pkg.all;
                use ieee.math_real.all;

            library work;
                use work.complex_pkg.all;
                use work.PyhaUtil.all;
                use work.Typedefs.all;
                use work.all;
            {IMPORTS}""")

        # add all converted classes to imports
        # look: https://github.com/tgingold/ghdl/issues/209
        from pyha.conversion.conversion import RecursiveConverter
        imports = [
            f'use work.{x}.all;'
            for x in RecursiveConverter.converted_modules.keys()
        ]
        return template.format(IMPORTS=formatter(imports))

    def build_constructor(self, prototype_only=False):
        template = textwrap.dedent("""\
            function {NAME}{ARGS} return self_t is
                -- constructor
                variable self: self_t;
            begin
            {DATA}
                return self;
            end function;""")

        data = [x._pyha_constructor() for x in self.data.elems]
        args = '; '.join([
            x._pyha_constructor_arg() for x in self.data.elems
            if x._pyha_constructor_arg() != ''
        ])
        if args != '':
            args = f'({args[:-2]})' if args[-2:] == '; ' else f'({args})'
        ret = template.format(NAME=escape_reserved_vhdl(self.name),
                              ARGS=args,
                              DATA=formatter(data))

        if prototype_only:
            return ret.splitlines()[0][:-3] + ';'
        return ret

    def build_data_structs(self):
        template = textwrap.dedent("""\
            type self_t is record
            {DATA}
            end record;""")

        data = [
            x._pyha_definition() for x in self.data.elems
            if not is_constant(x._name)
        ]
        if not data:
            data = ['dummy: integer;']
        return template.format(DATA=formatter(data))

    def build_constants(self):
        template = textwrap.dedent("""\
            type self_t_const is record
            {DATA}
            end record;""")

        data = [
            x._pyha_definition() for x in self.data.elems if const_filter(x)
        ]

        if not data:
            data = ['DUMMY: integer;']
        return template.format(DATA=formatter(data))

    def build_typedefs(self):
        # self typedefs
        typedefs = [
            x._pyha_typedef() for x in self.data.elems
            if x._pyha_typedef() is not None
        ]

        # local vars
        for function in self.value:
            if not isinstance(function, DefNodeVHDL):
                continue
            variables = [
                init_vhdl_type(name, val, val)
                for name, val in function.data.get_local_types().items()
            ]
            typedefs += [
                x._pyha_typedef() for x in variables
                if x is not None and x._pyha_typedef() is not None
            ]
        typedefs = list(dict.fromkeys(typedefs))  # get rid of duplicates
        return typedefs

    def build_package_header(self):
        template = textwrap.dedent("""\
            {MULTILINE_COMMENT}
            package {NAME} is
            {SELF_T}
            {SELF_ARRAY_TYPEDEF}
            
            {CONST_SELF_T}
            {CONST_SELF_ARRAY_TYPEDEF}

            {FUNC_HEADERS}
            end package;""")

        sockets = {}
        sockets['MULTILINE_COMMENT'] = self.multiline_comment
        sockets['NAME'] = self.data._pyha_module_name()

        # data-structure without constants ie. registers
        sockets['SELF_T'] = tabber(self.build_data_structs())
        sockets[
            'SELF_ARRAY_TYPEDEF'] = f'    type {self.data._pyha_arr_type_name()} is array (natural range <>) of {self.data._pyha_type()};'

        # only constants
        with TypeAppendHack('_const'):
            sockets['CONST_SELF_T'] = tabber(self.build_constants())
            sockets[
                'CONST_SELF_ARRAY_TYPEDEF'] = f'    type {self.data._pyha_arr_type_name()} is array (natural range <>) of {self.data._pyha_type()};'

        proto = '\n'.join(
            x.build_function(prototype_only=True) for x in self.value
            if isinstance(x, DefNodeVHDL))
        proto += '\n' + self.build_constructor(prototype_only=True) + '\n'
        sockets['FUNC_HEADERS'] = tabber(proto)

        return template.format(**sockets)

    def build_package_body(self):
        template = textwrap.dedent("""\
            package body {NAME} is
            {USER_FUNCTIONS}
            
            {CONSTRUCTOR}
            end package body;""")

        sockets = {}
        sockets['NAME'] = self.data._pyha_module_name()

        sockets['CONSTRUCTOR'] = tabber(self.build_constructor())
        # sockets['INIT_SELF'] = tabber(self.build_init())
        # sockets['CONSTANT_SELF'] = tabber(self.build_reset_constants())
        # sockets['RESET_SELF'] = tabber(self.build_reset())
        # sockets['UPDATE_SELF'] = tabber(self.build_update_registers())
        sockets['USER_FUNCTIONS'] = '\n\n'.join(
            tabber(str(x)) for x in self.value if isinstance(x, DefNodeVHDL))

        return template.format(**sockets)

    def __str__(self):
        template = textwrap.dedent("""\
            {FILE_HEADER}
            {IMPORTS}

            {PACKAGE_HEADER}

            {PACKAGE_BODY}
            """)

        sockets = {}
        sockets['FILE_HEADER'] = file_header()
        sockets['IMPORTS'] = self.build_imports()
        sockets['PACKAGE_HEADER'] = self.build_package_header()
        sockets['PACKAGE_BODY'] = self.build_package_body()
        return template.format(**sockets)
示例#2
0
 def object_class_name(self) -> str:
     # make sure we escape reserved names
     mod = VHDLModule('-', self.simulated_object)
     return mod._pyha_module_name()