# Simple tool to rewrite a Mentor versioned traces file from a seemingly randomly ordered file # into an equivalent but deterministically ordered traces file better fit for comparisons # # Rev 1.0 : 27-may-2013 import sys import string usage_string = ' Usage: \n' \ + ' python reorder_traces -i input_traces_file \n' \ + ' [-o output_sorted_traces_file] \n' \ + ' [--skip_power_nets] \n' \ + ' with: \n' \ + ' -i input_mentor_traces_file : required input file name \n' \ + ' -o output_sorted_traces_file : optional output file name, the default \n' \ + ' is to append ".alf" to input file name \n' \ + ' --skip_power_nets : ground and bulk power nets \n' \ + ' are suppressed from output \n' # define the power nets power_nets = ( "'GROUND'", "'BULK_2V5'", "'BULK_3V3'" ) # default initial parameter values input_trace_file_name = "" output_trace_file_name = "" skip_power_nets = 0 # read and parse command line arguments #-------------------------------- command_line_argument = sys.argv[1:] cmdarg_tot = len ( command_line_argument ) cmdarg_num = 0 while ( cmdarg_num < cmdarg_tot ) : # special switches if ( command_line_argument[cmdarg_num] == "--skip_power_nets" ) : skip_power_nets = 1 # check for known argument switch and that there will always be a filename after the switch elif ( ( command_line_argument[cmdarg_num] not in ( "-i", "-o" ) ) or ( cmdarg_num+1 >= cmdarg_tot ) or ( command_line_argument[cmdarg_num+1][:1] == "-" ) ) : status = "Command line error at argument <%s>" % command_line_argument[cmdarg_num] print status #app_logfile.write ( "\n%s\n" % status ) print usage_string sys.exit( 1 ) # input traces file name elif ( command_line_argument[cmdarg_num] == "-i" ) : input_trace_file_name = command_line_argument[cmdarg_num+1] # output net list file name elif ( command_line_argument[cmdarg_num] == "-o" ) : output_trace_file_name = command_line_argument[cmdarg_num+1] cmdarg_num = cmdarg_num + 2 # verify we have an input file if ( input_trace_file_name == "" ) : status = "Please provide Mentor traces input file" print status #app_logfile.write ( "\n%s\n" % status ) print usage_string sys.exit( 1 ) if ( output_trace_file_name == "" ) : output_trace_file_name = input_trace_file_name + ".alf" # open the files input_trace_file = open ( input_trace_file_name, "r" ) output_trace_file = open ( output_trace_file_name, "w" ) # simply copy the header stuff to the output file ; up to the first NET comment input_trace_line = input_trace_file.readline () while ( ( input_trace_line != '' ) and ( input_trace_line[:5] != "# NET" ) ) : output_trace_file.write ( input_trace_line ) input_trace_line = input_trace_file.readline () # Now read in all the nets and remember them in a dictionary net_dict = {} # clear dictionary found_end_of_file = 0 # prepare flag for finding last record while ( found_end_of_file == 0 ) : # repeat for every net until last record has been found and flagged net_comment = input_trace_line # the NET comment will be the tag for the dictionary entry for this net wire_dict = {} # this will be the dictionary for sorting the wires for this net wire_num = 0 # this will be incremented to become the tag for each wire entry for this net net_wire = "" # this will be the content of each wire entry # read first line after the NET comment input_trace_line = input_trace_file.readline () # repeat for all statements in this net (i.e. until next NET comment) while ( input_trace_line[:5] != "# NET" ) : # look for the end of the file, just take note for now, # and start by treating as end of this net, i.e. exit while section if ( ( input_trace_line[:3] == "ST " ) or ( input_trace_line == '' ) ) : found_end_of_file = 1 break #look for the beginning of a wire segment if ( input_trace_line[:3] in ( "WIR", "INC", "ANT", "GUI" ) ) : # let's simply call all these "wire declarations" # if this is not the first wire, save the previous one if ( wire_num != 0 ) : wire_dict [ "%s" % wire_num ] = net_wire # start a new wire record either way wire_num += 1 net_wire = input_trace_line else : # one more segment for current wire net_wire = "%s%s" % ( net_wire, input_trace_line ) #read next line input_trace_line = input_trace_file.readline () # don't forget to record the last wire from this net if ( wire_num != 0 ) : # check... but there shouldn't be net declaration without wires anyway wire_dict [ "%s" % wire_num ] = net_wire else : print "??? NET comment without wire entries <%s>" % net_comment[:-1] # build a sorted version of the list of wires for this net sorted_net_traces = "" sorted_wires = sorted ( wire_dict.iteritems(), key=lambda x:x[1] ) for wire_num in range ( len(sorted_wires) ) : sorted_net_traces = "%s%s" % ( sorted_net_traces, sorted_wires[wire_num][1] ) # show progress and detect multiple NET entries #print net_comment[:-1] # this skips the end of line character if net_dict.has_key ( net_comment ) : print "multiple NET entries for <%s>" % net_comment # record this net (unless it needs to be skipped over) record_this_net = 1 if ( skip_power_nets == 1 ) : for power_net in power_nets : if ( string.find( net_comment, power_net ) > 0 ) : record_this_net = 0 if ( record_this_net == 1 ) : net_dict[ net_comment ] = sorted_net_traces # done scanning, so now we cab write the NET traces in alphabetical order for net in sorted ( net_dict.keys() ) : output_trace_file.write( net ) output_trace_file.write( net_dict[ net ] ) # and write last line detected earlier, i.e last ST statement output_trace_file.write ( input_trace_line ) # done print "Sorted %d NET entries" % len ( net_dict ) input_trace_file.close () output_trace_file.close ()