#!/bin/python # Copyright 2018 Jan Moritz Joseph # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ############################################################################### import xml.etree.ElementTree as ET from xml.dom import minidom import numpy as np ############################################################################### class Writer: """ A base class for DataWriter, MapWriter and NetwrokWriter """ def __init__(self, root_node_name): root_node = ET.Element(root_node_name) root_node.set('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance') self.root_node = root_node def write_file(self, output_file): """ Write the xml file on disk """ rough_string = ET.tostring(self.root_node, 'utf-8') reparsed = minidom.parseString(rough_string) data = reparsed.toprettyxml(indent=" ") of = open(output_file, 'w') of.write(data) of.close() ############################################################################### class DataWriter(Writer): """ The class which is responsible of writing the tasks/data file """ def add_dataTypes_node(self, data_types): """ Add all DataTypes Parameters: - data_types: a list of data types """ dataTypes_node = ET.SubElement(self.root_node, 'dataTypes') for i in range(0, len(data_types)): self.add_dataType_node(dataTypes_node, i, data_types[i]) def add_dataType_node(self, parent_node, id, value): """ Individual DataType Parameters: - parent_node: the parent node - id: the id of the added data type - value: the value of the data type """ dataType_node = ET.SubElement(parent_node, 'dataType') dataType_node.set('id', str(id)) name_node = ET.SubElement(dataType_node, 'name') name_node.set('value', str(value)) def add_tasks_node(self): """ Adding the tasks-node of all tasks and returns it """ return ET.SubElement(self.root_node, 'tasks') def add_task_node(self, parent_node, t_id, start=(0, 0), duration=(-1, -1), repeat=(1, 1)): """ Adding a template task node without generates and requires tags Parameters: - parent_node: the parent node - t_id: the id of the task - start: the minimum and maximum start time - duration: the minimum and maximum duration - repeat: the minimum and maximum repeat Return: - The added task """ task_node = ET.SubElement(parent_node, 'task') task_node.set('id', str(t_id)) start_node = ET.SubElement(task_node, 'start') start_node.set('min', str(start[0])) start_node.set('max', str(start[1])) duration_node = ET.SubElement(task_node, 'duration') duration_node.set('min', str(duration[0])) duration_node.set('max', str(duration[1])) repeat_node = ET.SubElement(task_node, 'repeat') repeat_node.set('min', str(repeat[0])) repeat_node.set('max', str(repeat[1])) return task_node def add_generates_node(self, parent_node): """ Adding a generates node Parameters: - parent_node: parent node Return: - the 'generates' node """ generates_node = ET.SubElement(parent_node, 'generates') return generates_node def add_possibility(self, parent_node, id, prob, delay, interval, count, dt_ix, dist_tasks): """ Adding a possibility Parameters: - parent_node: the parent node - id: the id of the possibility - prob: the probability of the possibility - delay: the delay time before a task starts sending the data - interval: the interval (clock cycle) - count: the number of packets to send as a list - dt_ix: the index of the sent data type - dist_tasks: a list of destination tasks """ possibility_node = ET.SubElement(parent_node, 'possibility') possibility_node.set('id', str(id)) probability_node = ET.SubElement(possibility_node, 'probability') probability_node.set('value', str(prob)) destinations_node = ET.SubElement(possibility_node, 'destinations') for i in range(0, len(dist_tasks)): # print(dt_ix,count,dist_tasks) # print(i) self.add_destination(destinations_node, i, delay, interval, count[i], dt_ix[i], dist_tasks[i]) def add_requires_node(self, parent_node): """ Adding a requires node Parameters: - parent_node: the parent node Return: - the 'requires' node """ requires_node = ET.SubElement(parent_node, 'requires') return requires_node def add_requirement(self, parent_node, id, type, source, count): """ Adding a requirement node Parameters: - parent_node: the parent node - id: the id of the requirment - type: the id of the data type - source: the id of the source task - count: the number of the required packets from the source task """ requirement_node = ET.SubElement(parent_node, 'requirement') requirement_node.set('id', str(id)) d_type_node = ET.SubElement(requirement_node, 'type') d_type_node.set('value', str(type)) source_node = ET.SubElement(requirement_node, 'source') source_node.set('value', str(source)) count_node = ET.SubElement(requirement_node, 'count') count_node.set('min', str(count)) count_node.set('max', str(count)) def add_destination(self, parent_node, id, delay, interval, count, dt_ix, dist_task): """ Adding a destination to a possibility Parameters: - parent_node: the parent node - id: the id of the destination - delay: the delay time before a task starts sending the data - interval: the interval (clock cycle) - count: the number of packets to send - dt_ix: the index of the sent data type - dist_tasks: a list of destination tasks """ destination_node = ET.SubElement(parent_node, 'destination') destination_node.set('id', str(id)) delay_node = ET.SubElement(destination_node, 'delay') delay_node.set('min', str(delay[0])) delay_node.set('max', str(delay[1])) interval_node = ET.SubElement(destination_node, 'interval') interval_node.set('min', str(interval)) interval_node.set('max', str(interval)) count_node = ET.SubElement(destination_node, 'count') count_node.set('min', str(count)) count_node.set('max', str(count)) d_type_node = ET.SubElement(destination_node, 'type') d_type_node.set('value', str(dt_ix)) d_task_node = ET.SubElement(destination_node, 'task') d_task_node.set('value', str(dist_task)) ############################################################################### class Map_AdditionWriter(Writer): def __init__(self,root_node_name,node_list=[]): super().__init__(root_node_name) self.node_list=node_list def add_address_Map(self,task,address): bind_node = ET.SubElement(self.root_node, 'bind') task_node = ET.SubElement(bind_node, 'task') task_node.set('value', str(task)) node_node = ET.SubElement(bind_node, 'address') node_node.set('value', str(hex(address))) def clear_all(self): """Clear all nodes from the root node.""" self.root_node.clear() self.node_list = [] def change_root (self,newRoot): self.node_list.append(self.root_node) self.root_node = ET.Element(newRoot) def write_file(self, output_file): """ Write the xml file on disk """ self.node_list.append(self.root_node) of = open(output_file, 'w') for i in self.node_list: rough_string = ET.tostring(i, 'utf-8') reparsed = minidom.parseString(rough_string) data = reparsed.toprettyxml(indent=" ") of.write(data) of.close() def add_cluster(self, node, cluster): bind_node = ET.SubElement(self.root_node, 'bind') task_node = ET.SubElement(bind_node, 'node') task_node.set('value', str(node)) node_node = ET.SubElement(bind_node, 'cluster') node_node.set('value', str(cluster)) def add_address_Map_param(self,param,address,size): bind_node = ET.SubElement(self.root_node, 'bind') task_node = ET.SubElement(bind_node, 'param') task_node.set('value', str(param)) node_node = ET.SubElement(bind_node, 'address') node_node.set('value', str(hex(address))) node_node = ET.SubElement(bind_node, 'size') #the size in bytes node_node.set('value', str(size)) def add_task_param(self,node,param_list): bind_node = ET.SubElement(self.root_node, 'bind') task_node = ET.SubElement(bind_node, 'node') task_node.set('value', str(node)) node_node = ET.SubElement(bind_node, 'param_list') node_node.set('value', str(param_list)) class MapWriter(Writer): """ The class which is responsible of writing the map file """ def add_bindings(self, tasks, nodes): """ Binding the tasks with their nodes Parameters: - tasks: a list of tasks - nodes: a list of nodes """ for t_id, n_id in zip(tasks, nodes): bind_node = ET.SubElement(self.root_node, 'bind') task_node = ET.SubElement(bind_node, 'task') task_node.set('value', str(t_id)) node_node = ET.SubElement(bind_node, 'node') node_node.set('value', str(n_id)) ############################################################################### class NetworkWriter(Writer): """ The Network writer class """ def __init__(self, config): Writer.__init__(self, 'network-on-chip') self.config = config if self.config.z == 1: self.z_step = 1 self.z_range = np.arange(0, 1, self.config.z) else: self.z_step = 1/(self.config.z - 1) self.z_range = np.arange(0, 1+self.z_step, self.z_step) self.x_step = [] self.x_range = [] for x in self.config.x: self.x_step.append(1/(x - 1)) self.x_range.append(np.arange(0, 1+self.x_step[-1], self.x_step[-1])) self.y_step = [] self.y_range = [] for y in self.config.y: self.y_step.append(1/(y - 1)) self.y_range.append(np.arange(0, 1+self.y_step[-1], self.y_step[-1])) self.nodeId_Layer = np.full((1,self.config.z), np.nan) def write_header(self): bufferDepthType_node = ET.SubElement(self.root_node, 'bufferDepthType') bufferDepthType_node.set('value', self.config.bufferDepthType) def write_layers(self): layers_node = ET.SubElement(self.root_node, 'layers') for i in range(0, self.config.z): layer_node = ET.SubElement(layers_node, 'layer') layer_node.set('value', str(i)) def write_nodeTypes(self): nodeTypes_node = ET.SubElement(self.root_node, 'nodeTypes') for i in range(0, self.config.z): nodeType_node = ET.SubElement(nodeTypes_node, 'nodeType') nodeType_node.set('id', str(i)) model_node = ET.SubElement(nodeType_node, 'model') model_node.set('value', 'RouterVC') routing_node = ET.SubElement(nodeType_node, 'routing') routing_node.set('value', self.config.routing) selection_node = ET.SubElement(nodeType_node, 'selection') selection_node.set('value', '1stFreeVC') clockDelay_node = ET.SubElement(nodeType_node, 'clockDelay') clockDelay_node.set('value', str(self.config.clockDelay[i])) arbiterType_node = ET.SubElement(nodeType_node, 'arbiterType') arbiterType_node.set('value', 'fair') for i in range(self.config.z, self.config.z*2): nodeType_node = ET.SubElement(nodeTypes_node, 'nodeType') nodeType_node.set('id', str(i)) model_node = ET.SubElement(nodeType_node, 'model') model_node.set('value', 'ProcessingElement') clockDelay_node = ET.SubElement(nodeType_node, 'clockDelay') clockDelay_node.set('value', '1') def write_nodes_node(self): nodes_node = ET.SubElement(self.root_node, 'nodes') return nodes_node def write_nodes(self, nodes_node, node_type): if node_type == 'Router': node_id = 0 else: nodecounts = [] for (x, y) in zip(self.config.x, self.config.y): nodecounts.append(x*y) node_id = sum(nodecounts) nodeType_id = 0 z = 0 for zi in self.z_range: idType = 0 for yi in self.y_range[z]: for xi in self.x_range[z]: node_node = ET.SubElement(nodes_node, 'node') node_node.set('id', str(node_id)) xPos_node = ET.SubElement(node_node, 'xPos') xPos_node.set('value', str(xi)) yPos_node = ET.SubElement(node_node, 'yPos') yPos_node.set('value', str(yi)) zPos_node = ET.SubElement(node_node, 'zPos') zPos_node.set('value', str(zi)) nodeType_node = ET.SubElement(node_node, 'nodeType') if node_type == 'Router': nodeType_node.set('value', str(nodeType_id)) else: nodeType_node.set('value', str(self.config.z+nodeType_id)) idType_node = ET.SubElement(node_node, 'idType') idType_node.set('value', str(idType)) layer_node = ET.SubElement(node_node, 'layer') layer_node.set('value', str(int(zi*(self.config.z-1)))) for j in range(0, self.config.z): if j == int(zi*(self.config.z-1)): a = np.full((1,self.config.z), np.nan) a[0,j] = node_id self.nodeId_Layer = np.concatenate((self.nodeId_Layer, a), axis=0) node_id += 1 idType += 1 z += 1 nodeType_id += 1 def make_port(self, ports_node, port_id, node_id): port_node = ET.SubElement(ports_node, 'port') port_node.set('id', str(port_id)) node_node = ET.SubElement(port_node, 'node') node_node.set('value', str(node_id)) bufferDepth_node = ET.SubElement(port_node, 'bufferDepth') #bufferDepth_node.set('value', str(self.config.bufferDepth)) for items in self.nodeId_Layer : for pos in range(0, self.config.z) : if node_id == items[pos] : bufferDepth_node.set('value', str(self.config.bufferDepth[pos]).replace(" ", "")) break buffersDepths_node = ET.SubElement(port_node, 'buffersDepths') buffersDepths_node.set('value', str(self.config.buffersDepths)) vcCount_node = ET.SubElement(port_node, 'vcCount') #vcCount_node.set('value', str(self.config.vcCount)) for items in self.nodeId_Layer : for pos in range(0, self.config.z) : if node_id == items[pos] : vcCount_node.set('value', str(self.config.vcCount[pos]).replace(" ", "")) break def make_con(self, connections_node, con_id, src_node, dst_node): #print("binding " + str(src_node) + " to " + str(dst_node)) dupCon = self.is_duplicate_con(connections_node, src_node, dst_node) if not dupCon: self.construct_con(connections_node, con_id, src_node, dst_node) return con_id + 1 return con_id def is_duplicate_con(self, connections_node, src_node, dst_node): for con in connections_node: check1 = False check2 = False for port in con.iter('port'): node = port.find('node') node_id = int(node.get('value')) if node_id == dst_node: check1 = True elif node_id == src_node: check2 = True if check1 and check2: return True return False def construct_con(self, connections_node, con_id, src_node, dst_node): con_node = ET.SubElement(connections_node, 'con') con_node.set('id', str(con_id)) #interface_node = ET.SubElement(con_node, 'interface') #interface_node.set('value', str(0)) ports_node = ET.SubElement(con_node, 'ports') self.make_port(ports_node, 0, src_node) self.make_port(ports_node, 1, dst_node) def write_connections(self): connections_node = ET.SubElement(self.root_node, 'connections') con_id = 0 node_id = 0 z = 0 nodecounts = [] for (x, y) in zip(self.config.x, self.config.y): nodecounts.append(x*y) nodecount = sum(nodecounts) already_connected = set() for zi in self.z_range: for yi in self.y_range[z]: for xi in self.x_range[z]: # create Local #print("connecting local from " + str(node_id) + " to " + str(node_id + nodecount)) connection_tuple = (min(node_id, node_id + nodecount), max(node_id , node_id +nodecount)) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) if xi > 0: # create West connection_tuple = (node_id - 1, node_id) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) #con_id = self.make_con(connections_node, con_id, node_id, node_id-1) if xi < 0.95: # create East connection_tuple = (node_id, node_id + 1) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) #con_id = self.make_con(connections_node, con_id, node_id, node_id+1) if yi > 0: # create South connection_tuple = (min(node_id, node_id-self.config.x[z]), max(node_id , node_id-self.config.x[z])) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) #con_id = self.make_con(connections_node, con_id, node_id, node_id-self.config.x[z]) if yi < 0.95: # create North connection_tuple = (min(node_id, node_id+self.config.x[z]), max(node_id , node_id+self.config.x[z])) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) #con_id = self.make_con(connections_node, con_id, node_id, node_id+self.config.x[z]) if zi > 0: # create Down x_finder = np.where(self.x_range[z - 1] == xi) x_index = -1 y_finder = np.where(self.y_range[z - 1] == yi) y_index = -1 if (len(x_finder[0]) != 0): x_index = x_finder[0][0] if (len(y_finder[0]) != 0): y_index = y_finder[0][0] if (x_index != -1 and y_index != -1): previous_node_count = 0 if (z > 1): previous_node_count = sum(nodecounts[ 0 : int(z) - 1 ]) dst_id = previous_node_count + y_index * self.config.y[z - 1] + x_index #print("connecting " + str(node_id) + " with " + str(dst_id)) connection_tuple = (min(node_id, dst_id), max(node_id , dst_id)) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) #con_id = self.make_con(connections_node, con_id, node_id, dst_id) if zi < 0.95: # create Up x_finder = np.where(self.x_range[z + 1] == xi) x_index = -1 y_finder = np.where(self.y_range[z + 1] == yi) y_index = -1 if (len(x_finder[0]) != 0): x_index = x_finder[0][0] if (len(y_finder[0]) != 0): y_index = y_finder[0][0] if (x_index != -1 and y_index != -1): previous_node_count = sum(nodecounts[ 0 : int(z) + 1 ]) dst_id = previous_node_count + y_index * self.config.y[z + 1] + x_index connection_tuple = (min(node_id, dst_id), max(node_id , dst_id)) if not connection_tuple in already_connected: con_id = self.make_con(connections_node, con_id, connection_tuple[1], connection_tuple[0]) already_connected.add(connection_tuple) #con_id = self.make_con(connections_node, con_id, node_id, dst_id) node_id += 1 z += 1 def write_network(self, file_name): self.write_header() self.write_layers() self.write_nodeTypes() nodes_node = self.write_nodes_node() self.write_nodes(nodes_node, 'Router') self.write_nodes(nodes_node, 'ProcessingElement') self.write_connections() self.write_file(file_name) ############################################################################### class ConfigWriter(Writer): """ The Config writer class """ def __init__(self, config): Writer.__init__(self, 'configuration') self.config = config def write_general(self): general_node = ET.SubElement(self.root_node, 'general') simulationTime_node = ET.SubElement(general_node, 'simulationTime') simulationTime_node.set('value', str(self.config.simulationTime)) outputToFile_node = ET.SubElement(general_node, 'outputToFile') outputToFile_node.set('value', 'true') outputToFile_node.text = 'report' def write_noc(self): noc_node = ET.SubElement(self.root_node, 'noc') nocFile_node = ET.SubElement(noc_node, 'nocFile') nocFile_node.text = 'config/network.xml' flitsPerPacket_node = ET.SubElement(noc_node, 'flitsPerPacket') flitsPerPacket_node.set('value', str(self.config.flitsPerPacket)) bitWidth_node = ET.SubElement(noc_node, 'bitWidth') bitWidth_node.set('value', str(self.config.bitWidth)) Vdd_node = ET.SubElement(noc_node, 'Vdd') Vdd_node.set('value', '5') def write_phase(self, synthetic_node, name, start, duration): phase_node = ET.SubElement(synthetic_node, 'phase') phase_node.set('name', name) distribution_node = ET.SubElement(phase_node, 'distribution') distribution_node.set('value', 'uniform') start_node = ET.SubElement(phase_node, 'start') start_node.set('min', str(start[0])) start_node.set('max', str(start[1])) duration_node = ET.SubElement(phase_node, 'duration') duration_node.set('min', str(duration[0])) duration_node.set('max', str(duration[1])) repeat_node = ET.SubElement(phase_node, 'repeat') repeat_node.set('min', '-1') repeat_node.set('max', '-1') delay_node = ET.SubElement(phase_node, 'delay') delay_node.set('min', '0') delay_node.set('max', '0') injectionRate_node = ET.SubElement(phase_node, 'injectionRate') injectionRate_node.set('value', '0.002') count_node = ET.SubElement(phase_node, 'count') count_node.set('min', '1') count_node.set('max', '1') hotspot_node = ET.SubElement(phase_node, 'hotspot') hotspot_node.set('value', '0') def write_synthetic(self, application_node): synthetic_node = ET.SubElement(application_node, 'synthetic') # write two phases as a template self.write_phase(synthetic_node, 'warmup', [100, 100], [1090, 1090]) self.write_phase(synthetic_node, 'run', [1100, 1100], [101100, 101100]) def write_task(self, application_node): dataFile_node = ET.SubElement(application_node, 'dataFile') dataFile_node.text = 'config/data.xml' mapFile_node = ET.SubElement(application_node, 'mapFile') mapFile_node.text = 'config/map.xml' def write_application(self): application_node = ET.SubElement(self.root_node, 'application') benchmark_node = ET.SubElement(application_node, 'benchmark') benchmark_node.text = self.config.benchmark if self.config.benchmark == 'synthetic': self.write_synthetic(application_node) elif self.config.benchmark == 'task': self.write_task(application_node) # data_writer = DataWriter('data') # data_writer.write_file('data.xml') # map_writer = MapWriter('map') # map_writer.write_file('map.xml') simulationFile_node = ET.SubElement(application_node, 'simulationFile') simulationFile_node.text = 'traffic/pipelinePerformance_2D/PipelineResetTB.xml' mappingFile_node = ET.SubElement(application_node, 'mappingFile') mappingFile_node.text = 'traffic/pipelinePerformance_2D/PipelineResetTBMapping.xml' netraceFile_node = ET.SubElement(application_node, 'netraceFile') netraceFile_node.text = 'traffic/netrace/example.tra.bz2' netraceStartRegion_node = ET.SubElement(application_node, 'netraceStartRegion') netraceStartRegion_node.set('value', '0') isUniform_node = ET.SubElement(application_node, 'isUniform') isUniform_node.set('value', 'false') numberOfTrafficTypes_node = ET.SubElement(application_node, 'numberOfTrafficTypes') numberOfTrafficTypes_node.set('value', '5') def write_node_verbose(self, verbose_node, node_name): node = ET.SubElement(verbose_node, node_name) function_calls_node = ET.SubElement(node, 'function_calls') function_calls_node.set('value', 'false') send_flit_node = ET.SubElement(node, 'send_flit') send_flit_node.set('value', 'false') send_head_flit_node = ET.SubElement(node, 'send_head_flit') receive_flit_node = ET.SubElement(node, 'receive_flit') receive_flit_node.set('value', 'false') receive_tail_flit_node = ET.SubElement(node, 'receive_tail_flit') receive_tail_flit_node.set('value', 'true') throttle_node = ET.SubElement(node, 'throttle') throttle_node.set('value', 'false') reset_node = ET.SubElement(node, 'reset') reset_node.set('value', 'false') if node_name == 'router': assign_channel_node = ET.SubElement(node, 'assign_channel') assign_channel_node.set('value', 'false') buffer_overflow_node = ET.SubElement(node, 'buffer_overflow') buffer_overflow_node.set('value', 'true') send_head_flit_node.set('value', 'true') def write_netrace_verbose(self, verbose_node): netrace_node = ET.SubElement(verbose_node, 'netrace') inject_node = ET.SubElement(netrace_node, 'inject') inject_node.set('value', 'true') eject_node = ET.SubElement(netrace_node, 'eject') eject_node.set('value', 'true') router_receive_node = ET.SubElement(netrace_node, 'router_receive') router_receive_node.set('value', 'true') def write_tasks_verbose(self, verbose_node): tasks_node = ET.SubElement(verbose_node, 'tasks') function_calls_node = ET.SubElement(tasks_node, 'function_calls') function_calls_node.set('value', 'true') xml_parse_node = ET.SubElement(tasks_node, 'xml_parse') xml_parse_node.set('value', 'false') data_receive_node = ET.SubElement(tasks_node, 'data_receive') data_receive_node.set('value', 'true') data_send_node = ET.SubElement(tasks_node, 'data_send') data_send_node.set('value', 'true') source_execute_node = ET.SubElement(tasks_node, 'source_execute') source_execute_node.set('value', 'false') def write_verbose(self): verbose_node = ET.SubElement(self.root_node, 'verbose') self.write_node_verbose(verbose_node, 'processingElements') self.write_node_verbose(verbose_node, 'router') self.write_netrace_verbose(verbose_node) self.write_tasks_verbose(verbose_node) def write_report(self): report_node = ET.SubElement(self.root_node, 'report') bufferReportRouters = ET.SubElement(report_node, 'bufferReportRouters') bufferReportRouters.text = str(self.config.bufferReportRouters).replace(",", "") def write_config(self, file_name): self.write_general() self.write_noc() self.write_application() self.write_verbose() self.write_report() self.write_file(file_name)