# -*- 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.')