Source code for xml2vhdl.xml2vhdl

# -*- coding: utf8 -*-
import os
import sys
from xml2vhdl.xml2vhdl_helpers import help
from xml2vhdl.xml2vhdl_helpers import string_io
from xml2vhdl.xml2vhdl_helpers import slave
from xml2vhdl.xml2vhdl_helpers import xml_gen
from xml2vhdl.xml2vhdl_helpers import xml_utils
from xml2vhdl.xml2vhdl_helpers import bus_definition
import xml.etree.ElementTree as ET
from .xml2slave import Xml2Slave
from .xml2ic import Xml2Ic
from .debugTestingGen import DebugTestingFileGenerate
from xml2vhdl.arguments import Arguments as Xml2VhdlArguments
from xml2vhdl.customlogging import customlogging as xml2vhdl_logging
from xml2vhdl.version import __version__ as version
from xml2vhdl.resources import get_resource_path


logger_yml_file = get_resource_path("logging.yml")
logger = xml2vhdl_logging.config_logger(name=__name__, logr_yml=logger_yml_file)
__str__ = "{name} {version}".format(name=__name__, version=version)

def xml2vhdl_exec(options, cli_args, xml_file_name, gen_type):
    xml_file_path = string_io.normalize_path(os.path.dirname(os.path.abspath(xml_file_name)))
    options.input_folder = list()
    options.input_file = [string_io.normalize_path(os.path.abspath(xml_file_name))]
    if options.relative_output_path != "":
        options.vhdl_output = os.path.join(xml_file_path, options.relative_output_path)
        options.xml_output = os.path.join(xml_file_path, options.relative_output_path)
    if options.xml_output not in options.path:
        options.path.append(options.xml_output)
    if gen_type == "ic" or gen_type == "transparent_ic":
        options.vhdl_top = options.input_file[0].split(".")[0]
        xml2ic = Xml2Ic(options, cli_args)
        del xml2ic
    else:
        xml2slave = Xml2Slave(options, cli_args)
        del xml2slave
    return options.path


[docs] class Xml2VhdlGenerate(object): """ """ def __init__(self, args): log_level = xml2vhdl_logging.logging.INFO self.logger = xml2vhdl_logging.config_logger(name=__name__, class_name=self.__class__.__name__, logr_yml=logger_yml_file, default_level=log_level) for attr in dir(args): self.logger.debug('{k}: {v}'.format(k=attr, v=getattr(args, attr))) if args.xml_help: help.print_help() sys.exit() if args.log: help.print_log() sys.exit() xml_list = list() input_folder_list = args.input_folder if input_folder_list: xml_list = string_io.file_list_generate(input_folder_list, '.xml') for n in args.input_file: xml_list.append(n) constant_dict = xml_utils.get_parameters_dict(args.constant) # building dependency tree depend_tree = list() for xml in xml_list: try: tree = ET.parse(xml) except ET.ParseError as e: self.logger.error('Malformed XML File: {}'.format(xml)) self.logger.error(e) exit() root = tree.getroot() depend = {"file": xml, "id": root.get('id'), "depend_on": [], "output": os.path.basename(xml).replace(".xml", "_output.xml")} if constant_dict: for node in root.iter('node'): if 'link' in node.attrib.keys(): if node.attrib['link'] == "BOARD": node.attrib['link'] = constant_dict["BOARD"] for node in root.iter(): link = node.get('link') hw_type = node.get('hw_type') if link is not None and hw_type != "netlist": # do not need to compile netlists, however the XML must be in the path if link not in depend['depend_on']: depend['depend_on'].append(link) for dep in depend_tree: if dep['id'] == depend['id']: self.logger.error('Duplicate XML ID Names in Supplied Files. Exclude one or change its ID. ID = {}'.format(dep['id'])) self.logger.error('File 1: {}. File 2: {}'.format(dep['file'], depend['file'])) exit() depend_tree.append(depend) precompiled_xml = list() for path in args.path: for root, dirs, files in os.walk(path): for filename in files: if os.path.splitext(filename)[1] == ".xml" and os.path.splitext(filename)[0].endswith("_output"): precompiled_xml.append(filename) # retrieving XML files from dependency tree bottom to up to create compile order compile_order = list() while True: stop = 1 for xml in depend_tree: if not xml['depend_on']: compile_order.append(xml) depend_tree.remove(xml) stop = 0 else: for file_link in xml['depend_on']: for xml_done in compile_order: if file_link in precompiled_xml or file_link == xml_done['output']: #print("Dependency found") if file_link in xml['depend_on']: xml['depend_on'].remove(file_link) stop = 0 if stop == 1: break # Checking if there are unresolved dependencies if depend_tree: self.logger.critical("Unresolved dependencies found: ") for n in depend_tree: self.logger.critical('\t{n}' .format(n=n)) self.logger.info('-' * 80) self.logger.info("Compile order:") for n in compile_order: self.logger.info('\t{id}' .format(id=n['id'])) external_list = list() for xml in compile_order: self.logger.info("Analysing: {file}" .format(file=xml['file'])) tree = ET.parse(xml['file']) root = tree.getroot() if root.get('hw_type') == "external": external_list.append(xml['file']) else: args.path = xml2vhdl_exec(args, list(), xml['file'], root.get('hw_type')) DebugTestingFileGenerate(compile_order, args.relative_output_path, args.vhdl_output, args.board_xml_file, args.gen_tb_packages, args.tb_package_exclude_list) logger.info(external_list)
[docs] class Xml2Vhdl(object): def __init__(self, **kwargs): if 'log_level' in kwargs: log_level = kwargs['log_level'] else: log_level = xml2vhdl_logging.logging.INFO self.logger = xml2vhdl_logging.config_logger(__name__, class_name=self.__class__.__name__, logr_yml=logger_yml_file, default_level=log_level) if 'input_file' in kwargs: input_file = kwargs['input_file'] else: input_file = list() if 'input_folder' in kwargs: input_folder = kwargs['input_folder'] else: input_folder = list() if 'path' in kwargs: generated_output_paths = kwargs['path'] else: generated_output_paths = list() if 'slave_library' in kwargs: slave_library = kwargs['slave_library'] else: slave_library = 'work' if 'bus_library' in kwargs: bus_library = kwargs['bus_library'] else: bus_library = 'work' if 'bus_definition_number' in kwargs: bus_definition_number = kwargs['bus_definition_number'] else: bus_definition_number = 0 if 'constant' in kwargs: constants = kwargs['constant'] else: constants = list() if 'clean' in kwargs: clean = kwargs['clean'] else: clean = False if 'relative_output_path' in kwargs: relative_output_path = kwargs['relative_output_path'] else: relative_output_path = os.path.normpath('../vhdl/generated') if 'gen_tb_packages' in kwargs: gen_tb_packages = kwargs['gen_tb_packages'] else: gen_tb_packages = False vhdl_record_name = 't_axi4lite_mmap_slaves' setattr(self, 'log', False) setattr(self, 'input_file', input_file) setattr(self, 'input_folder', input_folder) setattr(self, 'path', generated_output_paths) setattr(self, 'bus_library', bus_library) setattr(self, 'slave_library', slave_library) setattr(self, 'bus_definition_number', bus_definition_number) setattr(self, 'relative_output_path', relative_output_path) setattr(self, 'vhdl_output', False) setattr(self, 'xml_output', False) setattr(self, 'xml_help', False) setattr(self, 'relocate_path', '') setattr(self, 'constant', constants) setattr(self, 'tb', False) setattr(self, 'top', '') setattr(self, 'vhdl_record_name', vhdl_record_name) setattr(self, 'zip', False) setattr(self, 'board_xml_file', '') setattr(self, 'gen_tb_packages', gen_tb_packages) setattr(self, 'tb_package_exclude_list', list()) setattr(self, 'clean', clean) setattr(self, 'generated_output_paths', generated_output_paths)
if __name__ == '__main__': args = Xml2VhdlArguments() Xml2VhdlGenerate(args) logger.info('Successfully Generated VHDL from XML.')