Source code for xml2ic

# -*- coding: utf8 -*-
"""

*************
``xml2ic.py``
*************

`GNU General Public License v3`_ © 2015-2019 University of Oxford & contributors

.. _GNU General Public License v3: _static/LICENSE

``xml2ic.py`` is a module provided to automatically generate ``AXI4-Lite`` Memory Mapped locations from
``XML`` descriptions, and is responsible for generating inter-connect (IC) blocks.

Todo:
    * error checking
    * documentation
    * regression test

"""
import re
import os
import sys
import zlib
import copy
import shutil
import binascii
import textwrap
import numpy as np
import xml.dom.minidom
import helper.string_io
import helper.arguments as arguments
import helper.bus_definition
import lxml.etree as ET
from xml2htmltable import xml2html

import helper.customlogging as xml2vhdl_logging
logger = xml2vhdl_logging.config_logger(__name__)

version = [1.8, "Replaced optparse with argparse",
           1.7, "major refactoring",
           1.6, "merge node correction",
           1.5, "bram init file containing zip compressed xml",
           1.4, "converted sys.exit() to sys.exit(1)",
           1.3, "merge attribute implementation",
           1.2, "byte size correction",
           1.1, "ic cascade support",
           1.0, "first release"]


# specific function
[docs]def ignore_check_offset(node_x, node_y): """ Args: node_x (???): node_y (???): Returns: (???): """ ret = False if is_leaf(node_x) and node_y == node_x.getparent(): ret = True elif is_leaf(node_y) and node_x == node_y.getparent(): ret = True elif is_leaf(node_x) and is_leaf(node_y) and node_x.getparent() == node_y.getparent(): ret = True return ret
# different function
[docs]def check_offset(root): """ Args: root (???): Returns: None """ # for node in root.findall('node'): for x in root.findall('node'): # print x.get('id') # print x.get('absolute_offset') x_address = int(x.get('absolute_offset'), 16) x_size = get_byte_size(x) # int(x.get('byte_size')) for y in root.findall('node'): y_address = int(y.get('absolute_offset'), 16) y_size = get_byte_size(y) # int(y.get('byte_size')) if x != y and ignore_check_offset(x,y) == False: if x_address >= y_address and x_address < y_address + y_size: logger.error("conflicting addresses:") logger.error("\t{}" .format(get_absolute_id(x), hex(x_address))) logger.error("\t{}" .format(get_absolute_id(x), hex(y_address))) sys.exit(1) if x_address + x_size - 1 >= y_address and x_address + x_size - 1 < y_address + y_size: logger.error("conflicting addresses:") logger.error("\t{}" .format(get_absolute_id(x), hex(x_address))) logger.error("\t{}" .format(get_absolute_id(x), hex(y_address))) sys.exit(1)
# different function
[docs]def check_offset_requirement(root): """ Args: root (???): Returns: None """ for x in root.findall('node'): if x.get('absolute_offset') != None: this_addr = int(x.get('absolute_offset'), 16) this_size = get_byte_size(x) # print x.get('id') # print this_addr # print this_size # print if this_addr & (this_size-1) != 0: logger.error("It should be (absolute_offset & (size-1)) = 0") logger.error("\t{} doesn't meet this requirement!" .format(get_absolute_id(x))) logger.error("\t{} absolute offset is: {}" .format(get_absolute_id(x), hex(this_addr))) logger.error("\t{} size is: {} bytes" .format(get_absolute_id(x), this_size)) sys.exit(1)
# specific function
[docs]def get_xml_file(link, path_list): """ Args: link (???): path_list (list of str): Returns: (???): """ link_found = "" for path in path_list: if path != "": path += "/" if os.path.isfile(helper.string_io.normalize_path(path + link)): link_found = helper.string_io.normalize_path(path + link) break if link_found == "": if os.path.isfile(helper.string_io.normalize_path(link)): link_found = link else: logger.error('Link "{}" Not Found!' .format(link)) sys.exit(1) return link_found
# specific function
[docs]def get_absolute_offset(node): """ Args: node (obj): Returns: None """ if node.get('address') != None: offset = int(node.get('address'), 16) else: offset = 0 current_node = node while True: parent_node = current_node.getparent() if parent_node == None: break else: if parent_node.get('address') != None: offset += int(parent_node.get('address'), 16) current_node = parent_node return helper.string_io.hex_format(offset)
# specific function
[docs]def get_absolute_id(node, excluded_levels=[]): """ Args: node (obj): excluded_levels (list of ???): Returns: (???): """ id = node.get('id') current_node = node level = 0 while True: parent_node = current_node.getparent() if parent_node is None: break else: if parent_node.get('id') != None and level not in excluded_levels: id = parent_node.get('id') + "." + id current_node = parent_node level += 1 return id
# specific function
[docs]def depth(node): """ Args: node (obj): Returns: (int): """ d = 0 while node is not None: d += 1 node = node.getparent() return d
# specific function
[docs]def is_leaf(node): """ Args: node (obj): Returns: (bool): """ if node.findall("node") == []: ret = True else: ret = False return ret
[docs]def get_byte_size(node): """ Args: node (obj): Returns: (int): """ x = node.get('byte_size') try: byte_size = int(x) except: try: byte_size = int(x, 16) except: if node.get('byte_size') != None: logger.error('Unsupported byte size attribute at node "{node_id}"' .format(node_id=node.get('id'))) sys.exit(1) else: byte_size = None return byte_size
[docs]def get_node_size(node): """Return the node total size Args: node (obj): Returns: (int): """ add_max = 0 for x in node.findall('node'): add = int(x.get('address'), 16) if get_byte_size(x) == None: return -1 elif get_byte_size(x) > 1: add += get_byte_size(x) if abs(add) > abs(add_max): add_max = add n = 0 while True: if abs(2**n) >= abs(add_max): break else: n += 1 return 2**n
[docs]def dec_check_bit(add_list, bit): """ Args: add_list (list of ???): bit (???): Returns: (int): position of not-equal bit among addresses in add_list, returns ``-1`` if there are not different bits """ for b in reversed(range(0, bit)): for add0 in add_list: for add1 in add_list: if add0[b] != add1[b]: return b return -1
[docs]def dec_get_last_bit(bit_path): """ Args: bit_path (str): Returns: (int): """ bit_list = bit_path.split("_") ret = bit_list[len(bit_list)-1] ret = re.sub(r'v.*', "", ret) ret = int(ret) logger.debug('get_last_bit input: {input}'.format(input=ret)) logger.debug('get_last_bit output: {output}'.format(output=bit_path)) if ret == -1: ret = 32 return ret
[docs]def dec_route_add(tree_dict): """ Args: tree_dict (dict): Returns: tuple: tuple containing: * int: 1 to indicate ``done`` complete. * dict: """ done = 0 logger.debug('tree_dict: {tree_dict}'.format(tree_dict=tree_dict)) for path in tree_dict.keys(): add_list = tree_dict[path] b = dec_check_bit(add_list,dec_get_last_bit(path)) if b > -1: list_0 = [] list_1 = [] for add in add_list: bit_dict = {} if add[b] == 0: list_0.append(add) else: list_1.append(add) logger.debug('{path} XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'.format(path=path)) logger.debug('{add_list_len}'.format(add_list_len=len(add_list))) logger.debug('{list_0_len}'.format(list_0_len=len(list_0))) logger.debug('{list_1_len}'.format(list_1_len=len(list_1))) logger.debug('{list_01_len}'.format(list_01_len=len(list_0) + len(list_1))) bit_dict["0"] = list_0 bit_dict["1"] = list_1 tree_dict[path + "_" + str(b) + "v0"] = list_0 tree_dict[path + "_" + str(b) + "v1"] = list_1 tree_dict[path] = [] done = 1 logger.debug('tree_dict: {tree_dict}'.format(tree_dict=tree_dict)) return done, tree_dict
[docs]def get_decoder_mask(address_list): """ Args: address_list (list of int): Returns: (dict): """ # addresses = [] # for x in get_object(["block","register_with_bitfield","register_without_bitfield"]): # addresses.append(global_dict[str(x)]['addressable']) addresses = address_list add_num = len(addresses) logger.info('Addresses are: {}' .format(add_num)) baddr = np.zeros((add_num, 32), dtype=np.int) decode_dict = {} tree_dict = {} # building address array a = 0 for add in sorted(addresses): bit_mask = 0x80000000 for n in range(32): if add & bit_mask != 0: baddr[a, 31-n] = 1 bit_mask = bit_mask >> 1 a = a + 1 logger.debug('baddr: {baddr}'.format(baddr=baddr)) tree_dict["-1v0"] = baddr while True: done, tree_dict = dec_route_add(tree_dict) if done == 0: break for bit_path in tree_dict: if tree_dict[bit_path] != []: add_bits = tree_dict[bit_path][0] add = "" for n in reversed(range(32)): add = add + str(add_bits[n]) bit_list = bit_path.split("_") mask = 0 for bit in bit_list: x = int(re.sub(r'v.*', "", bit)) if x >= 0: mask = mask | (1 << x) decode_dict[str(int(add, 2))] = mask logger.debug('Decode Dict:') for address in sorted(decode_dict.keys()): logger.debug('\taddr:') logger.debug('\t{address}'.format(address=address)) logger.debug('\tmask:') logger.debug('\t{mask}'.format(mask=hex(decode_dict[address]))) return decode_dict
[docs]class Xml2Ic: """ """ def __init__(self, options, args): self.logger = xml2vhdl_logging.config_logger(name=__name__, class_name=self.__class__.__name__) bus = helper.bus_definition.BusDefinition(int(options.bus_definition_number)) self.logger.info('-' * 80) self.logger.info('xml2ic.py version {}"' .format(version[0])) self.logger.info('Processing Paths:') for n in options.path: logger.info('\t{path}' .format(path=os.path.abspath(n))) cmd_str = "" for k in sys.argv: if k[0] == "-": cmd_str += "\n" cmd_str += k + " " # print cmd_str if options.log is True: self.logger.info('-' * 80) self.logger.info("History Log:") self.logger.info('-' * 80) for n in range(len(version)/2): self.logger.info("version {}" .format(version[2*n])) dedented_text = textwrap.dedent(re.sub(r" +", ' ', version[2*n+1])).strip() self.logger.info(textwrap.fill(dedented_text, width=80)) self.logger.info('-' * 80) sys.exit() input_file_list = [] input_folder_list = options.input_folder if input_folder_list != []: input_file_list = helper.string_io.file_list_generate(input_folder_list, '.xml') for n in options.input_file: input_file_list.append(n) if args != []: self.logger.error("Unexpected argument: {}" .format(args[0])) self.logger.error("-h for help") sys.exit(1) if input_file_list == []: self.logger.error("No input file!") self.logger.error("-h for help") sys.exit(1) for input_file_name in input_file_list: # input_file_name = options.input_file vhdl_output_folder = helper.string_io.normalize_output_folder(options.vhdl_output) if options.xml_output == "": output_file_name = input_file_name else: output_file_name = helper.string_io.normalize_path(input_file_name).split("/")[-1] xml_output_folder = os.path.abspath(helper.string_io.normalize_output_folder(options.xml_output)) tree = ET.parse(input_file_name) root = tree.getroot() if options.zip == True: myxml = xml.dom.minidom.parseString(ET.tostring(root)) # or xml.dom.minidom.parse('xmlfile.xml') myxml = myxml.toprettyxml() myxml = re.sub(r"\t", " ", myxml) myxml = re.sub(r"> *", ">", myxml) myxml = re.sub(r"\n\s*\n", "\n\n", myxml) myxml = re.sub("\n\n", "\n", myxml) xml_file_name = output_file_name xml_file_name = re.sub(r".*?\.", "", xml_file_name[::-1])[::-1] xml_file_name = xml_file_name + "_output.xml" xml_compressed = zlib.compress(myxml) xml_compressed = binascii.hexlify(xml_compressed) xml_compressed = helper.string_io.hex_format(len(xml_compressed)/2) + xml_compressed bram_init = "" if len(xml_compressed) % 8 != 0: xml_compressed += "0"*(8-(len(xml_compressed) % 8)) for n in range(0, len(xml_compressed)/8): word = xml_compressed[8*n:8*n+8] bram_init += word + "\n" bram_init_file_name = re.sub(r".*?\.", "", xml_file_name[::-1])[::-1] bram_init_file_name = bram_init_file_name + ".hex" bram_init_file = open(helper.string_io.normalize_path(os.path.join(xml_output_folder, bram_init_file_name)), "w") bram_init_file.write(bram_init) bram_init_file.close() self.logger.info("Done!") self.logger.info('-' * 80) sys.exit() # resolve links while True: todo = 0 for node in root.iter('node'): if 'hw_type' in node.attrib.keys(): hw_type = node.attrib['hw_type'] else: hw_type = "" if 'link' in node.attrib.keys() and not ('link_done' in node.attrib.keys()): link = get_xml_file(node.attrib['link'], options.path) link_tree = ET.parse(link) link_root = link_tree.getroot() # if hw_type == "transparent_ic": # for child in link_root: # node.extend(child) # else: node.extend(link_root) if node.get("hw_type") == "transparent_ic": node.set("hw_type", "transparent_ic_to_merge") elif link_root.get("hw_type") == "ic": node.set("hw_type", "ic_to_merge") if link_root.get('byte_size') != None: node.set('byte_size', link_root.get('byte_size')) node.set('link_done', node.attrib['link']) node.attrib.pop('link') todo = 1 if todo == 0: break # while True: # todo = 0 # for node in root.iter('node'): # if 'hw_type' in node.attrib.keys(): # hw_type = node.attrib['hw_type'] # else: # hw_type = "" # if 'link' in node.attrib.keys() and not ('link_done' in node.attrib.keys()): # link = get_xml_file(node.attrib['link'], options.path) # link_tree = ET.parse(link) # link_root = link_tree.getroot() # # node.extend(link_root) # node.set("hw_type", "ic_to_merge") # if link_root.get('byte_size') != None: # node.set('byte_size', link_root.get('byte_size')) # node.set('link_done', node.attrib['link']) # node.attrib.pop('link') # todo = 1 # # # # if hw_type == "transparent_ic": # # print link_root.get("id") # # raw_input() # # for child in link_root: # # print child # # # # xmlaaa = xml.dom.minidom.parseString(ET.tostring(child)) # or xml.dom.minidom.parse('xmlfile.xml') # # pretty_xml_as_string = xmlaaa.toprettyxml() # # # # # # # # print pretty_xml_as_string # # raw_input() # # # # node.extend(child) # # else: # # node.extend(link_root) # # node.set("hw_type", "ic_to_merge") # # # # if link_root.get('byte_size') != None: # # node.set('byte_size', link_root.get('byte_size')) # # node.set('link_done', node.attrib['link']) # # node.attrib.pop('link') # # todo = 1 # if todo == 0: # break # write Address and absolute id and absolute offset for node in root.iter('node'): if node != root: absolute_id = get_absolute_id(node) node.set('absolute_id', absolute_id) absolute_offset = get_absolute_offset(node) node.set('absolute_offset', absolute_offset) if node.get('address') != None: node.set('address', "0x" + helper.string_io.hex_format(int(node.get('address'), 16))) # check byte size on first level child nodes for node in root.findall("node"): if node != root: # print node.get('absolute_id') # print node.get('absolute_offset') if node.get('byte_size') == None and node.get('size') != None: node.set('byte_size', str(int(node.get('size')) * 4)) elif node.get('byte_size') == None: self.logger.error("Unknown byte size for node: {node}" .format(node=absolute_id)) self.error('Exiting...') sys.exit(1) check_offset(root) check_offset_requirement(root) root.set('byte_size', str(get_node_size(root))) # # VHDL generation # vhdl_start_node = None if options.vhdl_top != "": self.logger.info('Searching for VHDL Top-Level: {top_level}' .format(top_level=options.vhdl_top)) for node in root.iter('node'): self.logger.debug('node: {node}'.format(node=node.get('absolute_id'))) if node.get('absolute_id') == options.vhdl_top: vhdl_start_node = node self.logger.info("VHDL Top-Level found!") break if root.get('id') == options.vhdl_top: vhdl_start_node = root if vhdl_start_node is None: self.logger.warning('VHDL Top-Level not found: {top_level}' .format(top_level=options.vhdl_top)) vhdl_start_node = root options.vhdl_top = root.get('id') self.logger.warning("\tUsing root node: {node}" .format(node=options.vhdl_top)) # self.logger.error('Exiting...') # sys.exit(1) else: self.logger.info("VHDL top level found!") vhdl_id = [] vhdl_address = [] for node in vhdl_start_node.findall('node'): vhdl_id.append(node.get('id')) vhdl_address.append(int(node.get('address'), 16)) vhdl_decoder_mask = get_decoder_mask(vhdl_address) max_len = helper.string_io.get_max_len(vhdl_id) snippet = "type " + options.vhdl_record_name + " is (\n" for address in sorted(vhdl_address): id = vhdl_id[vhdl_address.index(address)] snippet += "\t" + "id_" + id + helper.string_io.add_space(id, max_len) + ",\n" snippet = snippet[0:-2] snippet += "\n);\n" snippet = helper.string_io.indent(snippet, 1) snippet = re.sub(r"\t", " ", snippet) slave_type = snippet snippet = "(" for address in sorted(vhdl_address): snippet += "X\"" + helper.string_io.hex_format(address) + "\"," snippet = snippet[0:-1] snippet += ")" slave_base_addr = snippet snippet = "(" for address in sorted(vhdl_address): snippet += "X\"" + helper.string_io.hex_format(vhdl_decoder_mask[str(address)]) + "\"," snippet = snippet[0:-1] snippet += ")" slave_mask = snippet # # MMAP PACKAGE # vhdl_package_name = bus.name + "_" + options.vhdl_top + "_mmap_pkg" vhdl_template = helper.string_io.read_template_file(os.path.dirname(os.path.abspath(__file__)) + "/template/" + "xml2vhdl" + "_mmap.template.vhd") vhdl_str = vhdl_template vhdl_str = vhdl_str.replace("<BUS>", bus.name) vhdl_str = vhdl_str.replace("<BUS_LIBRARY>", options.bus_library) vhdl_str = vhdl_str.replace("<TOP_LEVEL>", options.vhdl_top) vhdl_str = vhdl_str.replace("<VHDL_RECORD>", options.vhdl_record_name) vhdl_str = re.sub("<PKG_NAME>", vhdl_package_name, vhdl_str) vhdl_str = re.sub("<SLAVE_TYPE>", slave_type, vhdl_str) vhdl_str = re.sub("<SLAVE_BASE_ADDR>", slave_base_addr, vhdl_str) vhdl_str = re.sub("<SLAVE_MASK>", slave_mask, vhdl_str) vhdl_file_name = vhdl_package_name + ".vhd" helper.string_io.write_vhdl_file(vhdl_file_name, vhdl_output_folder, vhdl_str) # # IC PACKAGE # vhdl_template = helper.string_io.read_template_file(os.path.dirname(os.path.abspath(__file__)) + "/template/" + bus.name + "/xml2vhdl_ic_pkg.template.vhd") vhdl_str = vhdl_template vhdl_str = vhdl_str.replace("<BUS>", bus.name) vhdl_str = vhdl_str.replace("<BUS_LIBRARY>", options.bus_library) vhdl_str = vhdl_str.replace("<TOP_LEVEL>", options.vhdl_top) vhdl_file_name = bus.name + "_" + options.vhdl_top + "_ic_pkg.vhd" helper.string_io.write_vhdl_file(vhdl_file_name, vhdl_output_folder, vhdl_str) # # IC # vhdl_template = helper.string_io.read_template_file(os.path.dirname(os.path.abspath(__file__)) + "/template/" + bus.name + "/xml2vhdl_ic.template.vhd",) vhdl_str = vhdl_template vhdl_str = vhdl_str.replace("<BUS>", bus.name) vhdl_str = vhdl_str.replace("<BUS_CLK>", bus.clock) vhdl_str = vhdl_str.replace("<BUS_RST>", bus.reset) vhdl_str = vhdl_str.replace("<BUS_RST_VAL>", bus.reset_val) vhdl_str = vhdl_str.replace("<BUS_LIBRARY>", options.bus_library) vhdl_str = vhdl_str.replace("<DSN_LIBRARY>", options.slave_library) vhdl_str = vhdl_str.replace("<TOP_LEVEL>", options.vhdl_top) vhdl_file_name = bus.name + "_" + options.vhdl_top + "_ic.vhd" helper.string_io.write_vhdl_file(vhdl_file_name, vhdl_output_folder, vhdl_str) # # EXAMPLE # slave_inst = "" for id in vhdl_id: snippet = "\n" + bus.name + "_" + id + "_inst: entity work." + bus.name + "_" + id + "\n" snippet += "port map(\n" snippet += "\t" + "<BUS_CLK> => <BUS_CLK>,\n" snippet += "\t" + "<BUS_RST> => <BUS_RST>,\n" snippet += "\t" + "<BUS>_mosi => axi4lite_mosi_arr(axi4lite_mmap_get_id(id_" + id + ")),\n" snippet += "\t" + "<BUS>_miso => axi4lite_miso_arr(axi4lite_mmap_get_id(id_" + id + "))\n" snippet += ");\n" slave_inst += snippet slave_inst = helper.string_io.indent(slave_inst,1) slave_inst = re.sub(r"\t", " ", slave_inst) vhdl_template = helper.string_io.read_template_file(os.path.dirname(os.path.abspath(__file__)) + "/template/" + "xml2vhdl" + "_example.template.vhd") vhdl_str = vhdl_template vhdl_str = re.sub("<SLAVE_INST>", slave_inst,vhdl_str) vhdl_str = vhdl_str.replace("<BUS>", bus.name) vhdl_str = vhdl_str.replace("<BUS_LIBRARY>", options.bus_library) vhdl_str = vhdl_str.replace("<DSN_LIBRARY>", options.slave_library) vhdl_str = vhdl_str.replace("<BUS_CLK>", bus.clock) vhdl_str = vhdl_str.replace("<BUS_RST>", bus.reset) vhdl_str = vhdl_str.replace("<TOP_LEVEL>", options.vhdl_top) vhdl_str = re.sub("<PKG_NAME>", vhdl_package_name, vhdl_str) vhdl_str = re.sub("<SLAVE_TYPE>", snippet, vhdl_str) #print vhdl_str vhdl_file_name = bus.name + "_" + options.vhdl_top + "_example.vho" helper.string_io.write_vhdl_file(vhdl_file_name, vhdl_output_folder, vhdl_str) # # XML generation # Merge nodes. It merges nodes flattening the XML hierarchical level. # for node in root.findall('node'): # find all children node if node.get('hw_type') == "ic_to_merge": # node_id = node.get('id') for x in node.findall('node'): id = x.get('id') add = int(x.get('address'), 16) merge_root = copy.deepcopy(x) for child in merge_root.iter('node'): if child.get('address') != None: child.set('id', id + "_" + child.get('id')) child.set('address', "0x" + helper.string_io.hex_format(int(child.get('address'), 16) + add)) abs_id = child.get("absolute_id").replace(".", "^", depth(x)) # depth is number of nodes to get to the root abs_id = abs_id.replace("^", ".", depth(x) - 1) abs_id = abs_id.replace("^", "_", 1) child.set('absolute_id', abs_id) node.remove(x) node.extend(merge_root) node.set('hw_type', node.get('hw_type').replace("to_merge", "merged")) elif node.get('hw_type') == "transparent_ic_to_merge": node_id = node.get('id') for x in node.findall('node'): id = x.get('id') add = int(node.get('address'), 16) merge_root = copy.deepcopy(x) merge_root.set('address', "0x" + helper.string_io.hex_format(int(merge_root.get('address'), 16) + add)) for child in merge_root.iter('node'): abs_id = child.get("absolute_id") abs_id = abs_id.replace("." + node_id + ".", ".") child.set('absolute_id', abs_id) root.append(merge_root) root.remove(node) node.set('hw_type', node.get('hw_type').replace("to_merge", "merged")) # setting root's children nodes as merge-able: root.set('hw_type', "ic") myxml = xml.dom.minidom.parseString(ET.tostring(root)) # or xml.dom.minidom.parse('xmlfile.xml') myxml = myxml.toprettyxml() myxml = re.sub(r"\t", " ", myxml) myxml = re.sub(r"> *", ">", myxml) myxml = re.sub(r"\n\s*\n", "\n\n", myxml) myxml = re.sub("\n\n", "\n", myxml) myxml += "<!-- This file has been automatically generated using xml_map_gen.py version " + str(version[0]) + " /!-->\n" xml_base_name = output_file_name xml_base_name = re.sub(r".*?\.", "", xml_base_name[::-1])[::-1] xml_base_name = xml_base_name + "_output.xml" xml_file_name = os.path.abspath(helper.string_io.normalize_path(os.path.join(xml_output_folder, xml_base_name))) self.logger.info('Writing XML output file: {xml_output_file}' .format(xml_output_file=xml_file_name)) xml_file = open(xml_file_name, "w") xml_file.write(myxml) xml_file.close() html_dir_name = helper.string_io.normalize_output_folder(xml_output_folder + "/html") html_file_name = helper.string_io.normalize_path(os.path.join(html_dir_name, xml_base_name.replace("_output.xml", "_output.html"))) self.logger.info('Generating HTML Tables from: {}' .format(xml_file_name)) xml2html(xml_file_name, html_file_name, cmd_str) shutil.copy(os.path.join(os.path.dirname(__file__), 'regtables.css'), html_dir_name) self.logger.info('Generated HTML File: {}' .format(html_file_name)) xml_compressed = zlib.compress(myxml) xml_compressed = binascii.hexlify(xml_compressed) xml_compressed = helper.string_io.hex_format(len(xml_compressed)/2) + xml_compressed bram_init = "" if len(xml_compressed) % 8 != 0: xml_compressed += "0"*(8-(len(xml_compressed) % 8)) for n in range(0, len(xml_compressed)/8): word = xml_compressed[8*n:8*n+8] bram_init += word + "\n" bram_init_file_name = re.sub(r".*?\.", "", xml_base_name[::-1])[::-1] bram_init_file_name = bram_init_file_name + ".hex" bram_init_file = open(helper.string_io.normalize_path(os.path.join(xml_output_folder, bram_init_file_name)), "w") bram_init_file.write(bram_init) bram_init_file.close() self.logger.info("Done!") self.logger.info('-' * 80)
# # # MAIN STARTS HERE # # if __name__ == '__main__': args = arguments.Arguments() xml2ic_inst = Xml2Ic(args, list()) del xml2ic_inst