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)
def object_class_name(self) -> str: # make sure we escape reserved names mod = VHDLModule('-', self.simulated_object) return mod._pyha_module_name()