Example #1
0
def _generate_group_checker(model, models, templates):
    global _cached_members

    groupname = model.get('name')
    checktype = _get_group_members_recursively(model, models)

    if checktype:
        checktype = (' &&\n' + (' ' * 6)).join(
            [f'(uhdmtype != uhdm{member})' for member in sorted(checktype)])
    else:
        checktype = 'false'

    files = {
        'group_header.h': config.get_output_header_filepath(f'{groupname}.h'),
        'group_header.cpp':
        config.get_output_source_filepath(f'{groupname}.cpp'),
    }

    for input, output in files.items():
        file_content = templates[input]
        file_content = file_content.replace('<GROUPNAME>', groupname)
        file_content = file_content.replace('<UPPER_GROUPNAME>',
                                            groupname.upper())
        file_content = file_content.replace('<CHECKTYPE>', checktype)
        file_utils.set_content_if_changed(output, file_content)

    return True
Example #2
0
def generate(models):
    with open(config.get_template_filepath('clone_tree.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CLONE_IMPLEMENTATIONS>', '')
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('clone_tree.cpp'), file_content)

    return True
Example #3
0
def generate(models):
    module_listeners = _generate_module_listeners(models)
    class_listeners = _generate_class_listeners(models)

    with open(config.get_template_filepath('ElaboratorListener.cpp'),
              'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace(
        '<MODULE_ELABORATOR_LISTENER>',
        (' ' * 10) + ('\n' + (' ' * 10)).join(module_listeners))
    file_content = file_content.replace(
        '<CLASS_ELABORATOR_LISTENER>',
        (' ' * 4) + ('\n' + (' ' * 4)).join(class_listeners))
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('ElaboratorListener.cpp'),
        file_content)

    return True
Example #4
0
def generate(models):
    vpi_get_value_classes = set()
    vpi_get_delay_classes = set()
    for model in models.values():
        modeltype = model['type']
        if modeltype != 'obj_def':
            continue

        classname = model['name']

        baseclass = classname
        while baseclass:
            for key, value in models[baseclass].allitems():
                if key == 'property' and value.get('card') == '1':
                    type = value.get('type')

                    if type == 'value':
                        vpi_get_value_classes.add(classname)

                    if type == 'delay':
                        vpi_get_delay_classes.add(classname)

            baseclass = models[baseclass]['extends']

    # headers = [ f"#include <uhdm/{model['name']}.h>" for model in models.values() ]
    headers = [
        f"#include <uhdm/{name}.h>" for name in sorted(
            set.union(vpi_get_value_classes, vpi_get_delay_classes))
    ]

    vpi_handle_by_name_body = [
        f'  if (object->GetSerializer()->symbolMaker.GetId(name) == static_cast<SymbolFactory::ID>(-1)) {{',
        '    return nullptr;', '  }',
        '  const BaseClass *const ref = object->GetByVpiName(std::string_view(name));',
        '  return (ref != nullptr) ? NewVpiHandle(ref) : nullptr;'
    ]

    vpi_handle_body = [
        '  auto [ref, ignored1, ignored2] = object->GetByVpiType(type);',
        '  return (ref != nullptr) ? NewHandle(ref->UhdmType(), ref) : nullptr;'
    ]

    vpi_iterate_body = [
        '  auto [ignored, refType, refVector] = object->GetByVpiType(type);',
        '  return (refVector != nullptr) ? NewHandle(refType, refVector) : nullptr;'
    ]

    vpi_get_body = [
        '  BaseClass::vpi_property_value_t value = obj->GetVpiPropertyValue(property);',
        '  return std::holds_alternative<int64_t>(value) ? std::get<int64_t>(value) : 0;'
    ]

    vpi_get_str_body = [
        '  BaseClass::vpi_property_value_t value = obj->GetVpiPropertyValue(property);',
        '  return std::holds_alternative<const char *>(value) ? const_cast<char *>(std::get<const char *>(value)) : nullptr;'
    ]

    vpi_get_value_body = [
        f'  const s_vpi_value* v = nullptr;', f'  switch (handle->type) {{'
    ] + [
        f'    case uhdm{classname}: v = String2VpiValue((({classname}*)obj)->VpiValue()); break;'
        for classname in sorted(vpi_get_value_classes)
    ] + [
        '    default: break;', f'  }}', f'  if (v != nullptr) *value_p = *v;'
    ] if vpi_get_value_classes else []

    vpi_get_delay_body = [
        f'  const s_vpi_delay* v = nullptr;',
        f'  switch (handle->type) {{',
    ] + [
        f'    case uhdm{classname}: v = String2VpiDelays((({classname}*)obj)->VpiDelay()); break;'
        for classname in sorted(vpi_get_delay_classes)
    ] + [
        '    default: break;', f'  }}', f'  if (v != nullptr) *delay_p = *v;'
    ] if vpi_get_delay_classes else []

    # vpi_user.cpp
    with open(config.get_template_filepath('vpi_user.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<HEADERS>', '\n'.join(headers))
    file_content = file_content.replace('<VPI_HANDLE_BY_NAME_BODY>',
                                        '\n'.join(vpi_handle_by_name_body))
    file_content = file_content.replace('<VPI_HANDLE_BODY>',
                                        '\n'.join(vpi_handle_body))
    file_content = file_content.replace('<VPI_ITERATE_BODY>',
                                        '\n'.join(vpi_iterate_body))
    file_content = file_content.replace('<VPI_SCAN_BODY>', '')
    file_content = file_content.replace('<VPI_GET_BODY>',
                                        '\n'.join(vpi_get_body))
    file_content = file_content.replace('<VPI_GET_STR_BODY>',
                                        '\n'.join(vpi_get_str_body))
    file_content = file_content.replace('<VPI_GET_VALUE_BODY>',
                                        '\n'.join(vpi_get_value_body))
    file_content = file_content.replace('<VPI_GET_DELAY_BODY>',
                                        '\n'.join(vpi_get_delay_body))
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('vpi_user.cpp'), file_content)

    return True
Example #5
0
def _generate_one_class(model, models, templates):
    header_file_content = templates['class_header.h']
    source_file_content = templates['class_source.cpp']
    classname = model['name']
    modeltype = model['type']
    group_headers = set()
    declarations = []
    data_members = []
    implementations = []
    forward_declares = set()

    Classname_ = classname[:1].upper() + classname[1:]
    Classname = Classname_.replace('_', '')

    if modeltype != 'class_def':
        # Builtin properties do not need to be specified in each models
        # Builtins: "vpiParent, Parent type, vpiFile, Id" method and field
        data_members.extend(_get_data_member('BaseClass', 'vpiParent', '1'))
        declarations.extend(
            _get_declaration(classname, 'BaseClass', 'vpiParent', '1'))
        implementations.extend(
            _get_implementation(classname, 'BaseClass', 'vpiParent', '1'))

        data_members.extend(
            _get_data_member('unsigned int', 'uhdmParentType', '1'))
        declarations.extend(
            _get_declaration(classname, 'unsigned int', 'uhdmParentType', '1'))
        implementations.extend(
            _get_implementation(classname, 'unsigned int', 'uhdmParentType',
                                '1'))

        data_members.extend(_get_data_member('string', 'vpiFile', '1'))
        declarations.extend(
            _get_declaration(classname, 'string', 'vpiFile', '1'))
        implementations.extend(
            _get_implementation(classname, 'string', 'vpiFile', '1'))

        data_members.extend(_get_data_member('unsigned int', 'uhdmId', '1'))
        declarations.extend(
            _get_declaration(classname, 'unsigned int', 'uhdmId', '1'))
        implementations.extend(
            _get_implementation(classname, 'unsigned int', 'uhdmId', '1'))

    type_specified = False
    for key, value in model.allitems():
        if key == 'property':
            name = value.get('name')
            vpi = value.get('vpi')
            type = value.get('type')
            card = value.get('card')

            Vpi = vpi[:1].upper() + vpi[1:]

            if name == 'type':
                type_specified = True
                declarations.append(
                    f'  {type} {Vpi}() const final {{ return {value.get("vpiname")}; }}'
                )
            else:  # properties are already defined in vpi_user.h, no need to redefine them
                data_members.extend(_get_data_member(type, vpi, card))
                declarations.extend(
                    _get_declaration(classname, type, vpi, card))
                implementations.extend(
                    _get_implementation(classname, type, vpi, card))

        elif key == 'extends' and value:
            header_file_content = header_file_content.replace(
                '<EXTENDS>', value)
            source_file_content = source_file_content.replace(
                '<EXTENDS>', value)

        elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
            name = value.get('name')
            vpi = value.get('vpi')
            type = value.get('type')
            card = value.get('card')

            if (card == 'any') and not name.endswith('s'):
                name += 's'
            real_type = type

            if key == 'group_ref':
                type = 'any'

            if type != 'any' and card == '1':
                forward_declares.add(f'class {type};')

            group_headers.update(_get_group_headers(type, real_type))
            data_members.extend(_get_data_member(type, name, card))
            declarations.extend(
                _get_declaration(classname, type, name, card, real_type))
            implementations.extend(
                _get_implementation(classname, type, name, card, real_type))

    if not type_specified and (modeltype == 'obj_def'):
        vpiclasstype = config.make_vpi_name(classname)
        declarations.append(
            f'  virtual unsigned int VpiType() const final {{ return {vpiclasstype}; }}'
        )

    if modeltype == 'class_def':
        # DeepClone() not implemented for class_def; just declare to narrow the covariant return type.
        declarations.append(
            f'  virtual {classname}* DeepClone(Serializer* serializer, ElaboratorListener* elaborator, BaseClass* parent) const override = 0;'
        )
    else:
        return_type = 'tf_call' if '_call' in classname else classname
        declarations.append(
            f'  virtual {return_type}* DeepClone(Serializer* serializer, ElaboratorListener* elaborator, BaseClass* parent) const override;'
        )

    declarations.append(
        '  virtual const BaseClass* GetByVpiName(std::string_view name) const override;'
    )
    declarations.append(
        '  virtual std::tuple<const BaseClass*, UHDM_OBJECT_TYPE, const std::vector<const BaseClass*>*> GetByVpiType(int type) const override;'
    )
    declarations.append(
        '  virtual vpi_property_value_t GetVpiPropertyValue(int property) const override;'
    )

    implementations.extend(_get_clone_implementation(model, models))
    implementations.extend(_get_GetByVpiName_implementation(model))
    implementations.extend(_get_GetByVpiType_implementation(model))
    implementations.extend(_get_GetVpiPropertyValue_implementation(model))

    if modeltype == 'class_def':
        header_file_content = header_file_content.replace('<FINAL_CLASS>', '')
        header_file_content = header_file_content.replace(
            '<FINAL_DESTRUCTOR>', '')
        header_file_content = header_file_content.replace(
            '<VIRTUAL>', 'virtual ')
        header_file_content = header_file_content.replace(
            '<OVERRIDE_OR_FINAL>', 'override')
        header_file_content = header_file_content.replace(
            '<DISABLE_OBJECT_FACTORY>',
            '#if 0 // This class cannot be instantiated')
        header_file_content = header_file_content.replace(
            '<END_DISABLE_OBJECT_FACTORY>', '#endif')
    else:
        header_file_content = header_file_content.replace(
            '<FINAL_CLASS>', ' final')
        header_file_content = header_file_content.replace(
            '<FINAL_DESTRUCTOR>', ' final')
        header_file_content = header_file_content.replace(
            '<VIRTUAL>', 'virtual ')
        header_file_content = header_file_content.replace(
            '<OVERRIDE_OR_FINAL>', 'final')
        header_file_content = header_file_content.replace(
            '<DISABLE_OBJECT_FACTORY>', '')
        header_file_content = header_file_content.replace(
            '<END_DISABLE_OBJECT_FACTORY>', '')

    header_file_content = header_file_content.replace('<EXTENDS>', 'BaseClass')
    header_file_content = header_file_content.replace('<CLASSNAME>', classname)
    header_file_content = header_file_content.replace('<UPPER_CLASSNAME>',
                                                      classname.upper())
    header_file_content = header_file_content.replace(
        '<METHODS>', '\n\n'.join(declarations))
    header_file_content = header_file_content.replace(
        '<MEMBERS>', '\n\n'.join(data_members))
    header_file_content = header_file_content.replace(
        '<GROUP_HEADER_DEPENDENCY>', '\n'.join(sorted(group_headers)))
    header_file_content = header_file_content.replace(
        '<TYPE_FORWARD_DECLARE>', '\n'.join(sorted(forward_declares)))

    source_file_content = source_file_content.replace('<CLASSNAME>', classname)
    source_file_content = source_file_content.replace(
        '<METHODS>', '\n'.join(implementations))

    file_utils.set_content_if_changed(
        config.get_output_header_filepath(f'{classname}.h'),
        header_file_content)
    file_utils.set_content_if_changed(
        config.get_output_source_filepath(f'{classname}.cpp'),
        source_file_content)
    return True
Example #6
0
def generate(models):
    factory_declarations = []
    factory_methods = []
    factory_purge = []
    factory_stats = []
    factory_object_type_map = []

    save_ids = []
    save_objects = []
    saves_adapters = []

    restore_ids = []
    restore_objects = []
    restore_adapters = []

    type_map = uhdm_types_h.get_type_map(models)

    for model in models.values():
        modeltype = model['type']
        if modeltype == 'group_def':
            continue

        classname = model['name']
        Classname_ = classname[:1].upper() + classname[1:]
        Classname = Classname_.replace('_', '')

        baseclass = model.get('extends', 'BaseClass') or 'BaseClass'

        if modeltype != 'class_def':
            factory_declarations.append(f'    {classname}Factory {classname}Maker;')
            factory_methods.append(f'    {classname}* Make{Classname_}() {{ return Make<{classname}>(&{classname}Maker); }}')
            factory_object_type_map.append(f'  case uhdm{classname} /* = {type_map["uhdm" + classname]} */: return {classname}Maker.objects_[index];')

            save_ids.append(f'  SetSaveId_(&{classname}Maker);')
            save_objects.append(f'  VectorOfanySaveAdapter<{classname}, {Classname}>()({classname}Maker.objects_, this, cap_root.initFactory{Classname}({classname}Maker.objects_.size()));')

            restore_ids.append(f'  SetRestoreId_(&{classname}Maker, cap_root.getFactory{Classname}().size());')
            restore_objects.append(f'  VectorOfanyRestoreAdapter<{classname}, {Classname}>()(cap_root.getFactory{Classname}(), this, {classname}Maker.objects_);')

            factory_purge.append(f'  {classname}Maker.Purge();')
            factory_stats.append(f'  stats.insert(std::make_pair("{classname}", {classname}Maker.objects_.size()));')

        factory_declarations.append(f'    VectorOf{classname}Factory {classname}VectMaker;')
        factory_methods.append(f'    std::vector<{classname}*>* Make{Classname_}Vec() {{ return Make<{classname}>(&{classname}VectMaker); }}')

        saves_adapters.append(f'template<typename U>')
        saves_adapters.append(f'struct Serializer::AnySaveAdapter<{classname}, U> {{')
        saves_adapters.append(f'  void operator()(const {classname} *const obj, Serializer *const serializer, U builder) const {{')
        saves_adapters.append(f'    AnySaveAdapter<{baseclass}, U>()(static_cast<const {baseclass}*>(obj), serializer, builder);')

        restore_adapters.append(f'template<typename U>')
        restore_adapters.append(f'struct Serializer::AnyRestoreAdapter<{classname}, U> {{')
        restore_adapters.append(f'  void operator()(U reader, Serializer *const serializer, {classname} *const obj) const {{')
        restore_adapters.append(f'    AnyRestoreAdapter<{baseclass}, U>()(reader, serializer, static_cast<{baseclass}*>(obj));')

        for key, value in model.allitems():
            if key == 'property':
                name = value.get('name')
                vpi = value.get('vpi')
                type = value.get('type')
                card = value.get('card')

                if name == 'type':
                    continue

                Vpi_ = vpi[:1].upper() + vpi[1:]
                Vpi = Vpi_.replace('_', '')

                if type in ['string', 'value', 'delay']:
                    saves_adapters.append(f'    builder.set{Vpi}(serializer->symbolMaker.Make(obj->{Vpi_}()));')
                    restore_adapters.append(f'    obj->{Vpi_}(serializer->symbolMaker.GetSymbol(reader.get{Vpi}()));')
                else:
                    saves_adapters.append(f'    builder.set{Vpi}(obj->{Vpi_}());')
                    restore_adapters.append(f'    obj->{Vpi_}(reader.get{Vpi}());')
            
            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                name = value.get('name')
                type = value.get('type')
                card = value.get('card')
                id = value.get('id')

                Type_ = type[:1].upper() + type[1:]
                Type = Type_.replace('_', '')

                if (card == 'any') and not name.endswith('s'):
                    name += 's'

                Name_ = name[:1].upper() + name[1:]
                Name = Name_.replace('_', '')

                real_type = type
                if key == 'group_ref':
                    type = 'any'

                if card == '1':
                    if key in ['class_ref', 'group_ref']:
                        saves_adapters.append(f'    if (obj->{Name_}() != nullptr) {{')
                        saves_adapters.append(f'      ::ObjIndexType::Builder tmp = builder.get{Name}();')
                        saves_adapters.append(f'      tmp.setIndex(serializer->GetId(obj->{Name_}()));')
                        saves_adapters.append(f'      tmp.setType((obj->{Name_}())->UhdmType());')
                        saves_adapters.append( '    }')

                        restore_adapters.append(f'    obj->{Name_}(({type}*)serializer->GetObject(reader.get{Name}().getType(), reader.get{Name}().getIndex() - 1));')
                    else:
                        saves_adapters.append(f'    builder.set{Name}(serializer->GetId(obj->{Name_}()));')

                        restore_adapters.append(f'    if (reader.get{Name}()) {{')
                        restore_adapters.append(f'      obj->{Name_}(serializer->{type}Maker.objects_[reader.get{Name}() - 1]);')
                        restore_adapters.append( '    }')

                else:
                    obj_key = '::ObjIndexType' if key in ['class_ref', 'group_ref'] else '::uint64_t'

                    saves_adapters.append(f'    if (obj->{Name_}() != nullptr) {{')
                    saves_adapters.append(f'      ::capnp::List<{obj_key}>::Builder {Name}s = builder.init{Name}(obj->{Name_}()->size());')
                    saves_adapters.append(f'      for (unsigned int i = 0, n = obj->{Name_}()->size(); i < n; ++i) {{')

                    restore_adapters.append(f'    if (reader.get{Name}().size() > 0) {{')
                    restore_adapters.append(f'      std::vector<{type}*>* vect = serializer->{type}VectMaker.Make();')
                    restore_adapters.append(f'      for (unsigned int i = 0, n = reader.get{Name}().size(); i < n; ++i) {{')

                    if key in ['class_ref', 'group_ref']:
                        saves_adapters.append(f'        ::ObjIndexType::Builder tmp = {Name}s[i];')
                        saves_adapters.append(f'        tmp.setIndex(serializer->GetId((*obj->{Name_}())[i]));')
                        saves_adapters.append(f'        tmp.setType(((BaseClass*)((*obj->{Name_}())[i]))->UhdmType());')

                        restore_adapters.append(f'        vect->push_back(({type}*)serializer->GetObject(reader.get{Name}()[i].getType(), reader.get{Name}()[i].getIndex() - 1));')
                    else:
                        saves_adapters.append(f'        {Name}s.set(i, serializer->GetId((*obj->{Name_}())[i]));')

                        restore_adapters.append(f'        vect->push_back(serializer->{type}Maker.objects_[reader.get{Name}()[i] - 1]);')

                    saves_adapters.append('      }')
                    saves_adapters.append('    }')

                    restore_adapters.append( '      }')
                    restore_adapters.append(f'      obj->{Name_}(vect);')
                    restore_adapters.append( '    }')

        saves_adapters.append('  }')
        saves_adapters.append('};')
        saves_adapters.append('')

        restore_adapters.append('  }')
        restore_adapters.append('};')
        restore_adapters.append('')

    uhdm_name_map = [
        'std::string UhdmName(UHDM_OBJECT_TYPE type) {',
        '  switch (type) {'
    ]
    uhdm_name_map.extend([ f'  case {name} /* = {id} */: return "{name[4:]}";' for name, id in uhdm_types_h.get_type_map(models).items() ])
    uhdm_name_map.append('  default: return "NO TYPE";')
    uhdm_name_map.append('}')
    uhdm_name_map.append('}')

    # Serializer.h
    with open(config.get_template_filepath('Serializer.h'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<FACTORIES>', '\n'.join(factory_declarations))
    file_content = file_content.replace('<FACTORIES_METHODS>', '\n'.join(factory_methods))
    file_utils.set_content_if_changed(config.get_output_header_filepath('Serializer.h'), file_content)

    # Serializer.cpp
    with open(config.get_template_filepath('Serializer.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<METHODS_CPP>', '') # Deprecated
    file_content = file_content.replace('<UHDM_NAME_MAP>', '\n'.join(uhdm_name_map))
    file_content = file_content.replace('<FACTORY_PURGE>', '\n'.join(factory_purge))
    file_content = file_content.replace('<FACTORY_STATS>', '\n'.join(factory_stats))
    file_content = file_content.replace('<FACTORY_OBJECT_TYPE_MAP>', '\n'.join(factory_object_type_map))
    file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer.cpp'), file_content)

    # Serializer_save.cpp
    with open(config.get_template_filepath('Serializer_save.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CAPNP_ID>', '\n'.join(save_ids))
    file_content = file_content.replace('<CAPNP_SAVE>', '\n'.join(save_objects))
    file_content = file_content.replace('<CAPNP_SAVE_ADAPTERS>', '\n'.join(saves_adapters))
    file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer_save.cpp'), file_content)

    # Serializer_restore.cpp
    with open(config.get_template_filepath('Serializer_restore.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CAPNP_INIT_FACTORIES>', '\n'.join(restore_ids))
    file_content = file_content.replace('<CAPNP_RESTORE_FACTORIES>', '\n'.join(restore_objects))
    file_content = file_content.replace('<CAPNP_RESTORE_ADAPTERS>', '\n'.join(restore_adapters))
    file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer_restore.cpp'), file_content)

    return True
Example #7
0
def _main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-output-dirpath',
                        dest='output_dirpath',
                        type=str,
                        help='Output path')
    parser.add_argument('--parallel',
                        dest='parallel',
                        action='store_true',
                        default=True)
    parser.add_argument('--source-dirpath',
                        dest='source_dirpath',
                        type=str,
                        help='Path to UHDM source')
    args = parser.parse_args()
    config.configure(args)

    print('Generating UHDM models ...')
    print('   Loading models ...')
    models = loader.load_models()
    print(f'   ... found {len(models)} models.')

    print('   Validating ordering ...')
    # Check validity
    index = 0
    order = {}
    for name in models.keys():
        order[name] = index
        index += 1

    for name, model in models.items():
        baseclass = model['extends']
        if baseclass:
            thisIndex = order[name]
            baseIndex = order[baseclass]
            if baseIndex >= thisIndex:
                raise Exception(
                    f'Model {name} should follow {baseclass} in listing.')
    print('   ... all good.')

    params = [
        ('capnp', [models]),
        ('class_hierarchy', [models]),
        ('classes', [models]),
        ('clone_tree_cpp', [models]),
        ('containers_h', [models]),
        ('ElaboratorListener_cpp', [models]),
        ('Copier', [{
            config.get_template_filepath('BaseClass.h'):
            config.get_output_header_filepath('BaseClass.h'),
            config.get_template_filepath('clone_tree.h'):
            config.get_output_header_filepath('clone_tree.h'),
            config.get_template_filepath('ElaboratorListener.h'):
            config.get_output_header_filepath('ElaboratorListener.h'),
            config.get_template_filepath('ExprEval.h'):
            config.get_output_header_filepath('ExprEval.h'),
            config.get_template_filepath('ExprEval.cpp'):
            config.get_output_source_filepath('ExprEval.cpp'),
            config.get_template_filepath('RTTI.h'):
            config.get_output_header_filepath('RTTI.h'),
            config.get_template_filepath('SymbolFactory.h'):
            config.get_output_header_filepath('SymbolFactory.h'),
            config.get_template_filepath('SymbolFactory.cpp'):
            config.get_output_source_filepath('SymbolFactory.cpp'),
            config.get_template_filepath('uhdm_vpi_user.h'):
            config.get_output_header_filepath('uhdm_vpi_user.h'),
            config.get_template_filepath('vpi_uhdm.h'):
            config.get_output_header_filepath('vpi_uhdm.h'),
            config.get_template_filepath('vpi_visitor.h'):
            config.get_output_header_filepath('vpi_visitor.h'),
            config.get_include_filepath('sv_vpi_user.h'):
            config.get_output_header_filepath('sv_vpi_user.h'),
            config.get_include_filepath('vhpi_user.h'):
            config.get_output_header_filepath('vhpi_user.h'),
            config.get_include_filepath('vpi_user.h'):
            config.get_output_header_filepath('vpi_user.h'),
        }]),
        ('serializer', [models]),
        ('uhdm_forward_decl_h', [models]),
        ('uhdm_h', [models]),
        ('uhdm_types_h', [models]),
        ('vpi_listener', [models]),
        ('vpi_user_cpp', [models]),
        ('vpi_visitor_cpp', [models]),
        ('VpiListener_h', [models]),
        ('VpiListenerTracer_h', [models]),
    ]

    if args.parallel:
        with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor:
            results = list(executor.map(_worker, params))
    else:
        results = [_worker(args) for args in params]
    print('... all done!')

    result = sum([0 if r else 1 for r in results])
    if result:
        print('ERROR: UHDM model generation FAILED!')
    else:
        print('UHDM Models generated successfully!.')

    return result
Example #8
0
def generate(models):
    visit_object_body = []
    private_visitor_bodies = []

    ignored_objects = set(['vpiNet'])

    for model in models.values():
        modeltype = model['type']
        if modeltype == 'group_def':
            continue

        classname = model['name']
        if classname in ['net_drivers', 'net_loads']:
            continue

        vpi_name = config.make_vpi_name(classname)
        if vpi_name not in ignored_objects:
            visit_object_body.append(
                f'    case {vpi_name}: visit_{classname}(obj_h, indent, relation, visited, out, shallowVisit); break;'
            )

        private_visitor_bodies.append(
            f'static void visit_{classname}(vpiHandle obj_h, int indent, const char *relation, VisitedContainer* visited, std::ostream& out, bool shallowVisit) {{'
        )

        baseclass = model.get('extends', None)
        if baseclass:
            private_visitor_bodies.append(
                f'  visit_{baseclass}(obj_h, indent, relation, visited, out, shallowVisit);'
            )

        itr_required = False
        private_visitor_body = []

        if classname == 'part_select':
            private_visitor_body.extend(
                _get_implementation(classname, 'vpiParent', '1'))
            itr_required = True

        if modeltype != 'class_def':
            private_visitor_body.extend(
                _get_vpi_xxx_visitor('string', 'vpiFile', '1'))

        type_specified = False
        for key, value in model.allitems():
            if key == 'property':
                name = value.get('name')
                vpi = value.get('vpi')
                type = value.get('type')
                card = value.get('card')

                type_specified = name == 'type' or type_specified
                private_visitor_body.extend(
                    _get_vpi_xxx_visitor(type, vpi, card))

            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                vpi = value.get('vpi')
                card = value.get('card')

                private_visitor_body.extend(
                    _get_implementation(classname, vpi, card))
                itr_required = True

        if not type_specified and (modeltype == 'obj_def'):
            private_visitor_body.extend(
                _get_vpi_xxx_visitor('unsigned int', 'vpiType', '1'))

        if private_visitor_body:
            if itr_required:
                private_visitor_bodies.append(f'  vpiHandle itr;')
            private_visitor_bodies.extend(private_visitor_body)

        private_visitor_bodies.append(f'}}')
        private_visitor_bodies.append('')

    visitors = [f'  switch (objectType) {{'
                ] + sorted(visit_object_body) + [f'  }}']

    # vpi_visitor.cpp
    with open(config.get_template_filepath('vpi_visitor.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<OBJECT_VISITORS>',
                                        '\n'.join(visitors))
    file_content = file_content.replace('<PRIVATE_OBJECT_VISITORS>',
                                        '\n'.join(private_visitor_bodies))
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('vpi_visitor.cpp'), file_content)

    return True
Example #9
0
def generate(models):
    individual_model_schemas = {}
    flattened_model_schemas = []
    root_schema_index = 2
    root_schema = []

    for model in models.values():
        modeltype = model['type']
        if modeltype == 'group_def':
            continue

        classname = model['name']
        individual_model_schemas[classname] = []

        Classname_ = classname[:1].upper() + classname[1:]
        Classname = Classname_.replace('_', '')

        if modeltype != 'class_def':
            individual_model_schemas[classname].append(('uhdmId', 'UInt64'))
            individual_model_schemas[classname].append(('vpiParent', 'UInt64'))
            individual_model_schemas[classname].append(('uhdmParentType', 'UInt64'))
            individual_model_schemas[classname].append(('vpiFile', 'UInt64'))
            individual_model_schemas[classname].append(('vpiLineNo', 'UInt32'))
            individual_model_schemas[classname].append(('vpiEndLineNo', 'UInt32'))
            individual_model_schemas[classname].append(('vpiColumnNo', 'UInt16'))
            individual_model_schemas[classname].append(('vpiEndColumnNo', 'UInt16'))

            root_schema.append(f'  factory{Classname} @{root_schema_index} :List({Classname});')
            root_schema_index += 1

        for key, value in model.allitems():
            if key == 'property':
                if value.get('name') != 'type':
                    vpi = value.get('vpi')
                    type = value.get('type')
                    card = value.get('card')
                    individual_model_schemas[classname].append(_get_schema(type, vpi, card))

            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                name = value.get('name')
                type = value.get('type')
                card = value.get('card')

                if (card == 'any') and not name.endswith('s'):
                    name += 's'

                name = name.replace('_', '')

                obj_key = 'ObjIndexType' if key in ['class_ref', 'group_ref'] else 'UInt64'
                individual_model_schemas[classname].append(_get_schema(obj_key, name, card))

        if modeltype != 'class_def':
            # Process the hierarchy tree top-down
            stack = []
            baseclass = classname
            while (baseclass):
                stack.append(baseclass)
                baseclass = models[baseclass]['extends']

            capnpIndex = 0
            flattened_model_schemas.append(f'struct {Classname} {{')

            while stack:
                for name, type in individual_model_schemas[stack.pop()]:
                    if name and type:
                        flattened_model_schemas.append(f'  {name} @{capnpIndex} :{type};')
                        capnpIndex += 1

            flattened_model_schemas.append('}')
            flattened_model_schemas.append('')

    with open(config.get_template_filepath('UHDM.capnp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CAPNP_SCHEMA>', '\n'.join(flattened_model_schemas))
    file_content = file_content.replace('<CAPNP_ROOT_SCHEMA>', '\n'.join(root_schema))
    file_utils.set_content_if_changed(config.get_output_source_filepath('UHDM.capnp'), file_content)

    return True