############################################## # This is the "List Components Pin Nets" utility (aka ListCompPinNets) # # Input: It takes one file: # # This input file gets executed as python commands # The default configuration name is "ListCompPinNets.cfg" # An alternate input file may be given with command line parameter <-c other_config_file_name> # # This Configuration file may include # (note all parameter names below must appear starting in column #1 of configuration file) # # - "netfile_list": # The list of netlist files as a python list called # This is an example for parsing only one netlist file: # netfile_list = ( "HubNets/atca_eds_strip_nets", ) # This configuration is optional and the default is an empty list (i.e. not very useful) # # - "skip_comp_prefix": # A python list with component name prefixes for which no output file will be generated # For example to skip standard resistors and capacitors # skip_comp_prefix = ( "R", "C" ) # The filter is case-NONsensitive -> the list must use uppercase while any case combination is filtered out # This configuration is optional and the default is to not skip any component # # - "component_file_name": # The name of a Mentor component file as a string variable # If a component file is given, the name of the output file will include the component name. # This configuration is optional and the default is to not read a component file # # - "comp_type_pin_name_dict_list": # The list of file names where each file corresponds to a component type and defines a pin name dictionaries called # This is an example for including one dictionary file # comp_type_pin_name_dict_list = ( "CompTypePinDicts/VCU125_FLVC2104.dct", ) # This information is optional and the default is an empty list (i.e. no pin name defined) # Each file should define a dictionary in the form # comp_type_dict[ "IC_XCVU125" ] = { # "A3" : "GND" , # ... # "BF44" : "NC" , # } # "comp_type_dict" is a dictionary where each entry key describes a component type. # Each entry value in this dictionary is a dictionary itself where # each entry key is a pin number string # and each value a pin name string. # The key name of each "comp_type_dict" entry needs to match the component type name in the Mentor component file. # # - "output_dir_name" # The name of a subdirectory as a string variable # A trailing space is required # This configuration is optional and the default is to use the local directory "./" # # - "include_pin_name": # A boolean variable (i.e. True or False) # If this variable is set to True each line listing a pin name will also show the pin name for that component type # (if a corresponding pin number to pin name dictionary has been supplied via comp_type_pin_name_dict_list above) # This configuration is optional and the default is skip including pin names # A Mentor component file must have been given for any pin name to be found. # Only pin names for components where a matching component type pin name dictionary was given will be listed. # # - "include_index" # A boolean variable (i.e. True or False) # If this variable is set to True each line listing a pin name will show which line of which net file it came from # This configuration is optional and the default is to skip generating an index # # - "include_sort_by_pin" # A boolean variable (i.e. True or False) # If this variable is set to False the list of pin sorted by pin number will be omitted # This configuration is optional and the default is to include this list. # # - "include_sort_by_name" # A boolean variable (i.e. True or False) # If this variable is set to False the list of pin sorted by net tname will be omitted # This configuration is optional and the default is to include this list. # # - "ucf_file_dict" # Add an entry to a dictionary of component reference names for which a Xilinx UCF file should be created. # For each entry, specify the desired UCF file name. # e.g.: ucf_file_dict [ "U1" ] = "Hub_FPGA_ucf.txt" # The default is to generate no UCF file # # - "xdc_file_dict" # Add an entry to a dictionary of component reference names for which a Xilinx XDC file should be created. # For each entry, specify the desired XDC file name. # e.g.: xdc_file_dict [ "U1" ] = "Hub_FPGA_xdc.txt" # The default is to generate no XDC file # # - "ucfxdc_skip_net_name_lst" # Provide a list of Net Names to be skipped when creating the UCF and XDC file(s) # e.g. ucfxdc_skip_net_name_lst = ( "GROUND", ) # The default is to skip nothing. # # - "ucfxdc_skip_comp_pin_ref_lst" # Provide a list of Component Reference Designator with Pin Name to be skipped when creating the UCF and XDC file(s) # e.g. ucfxdc_skip_comp_pin_ref_lst = ( "U1-BE16", ) # The default is to skip nothing. # # Output files: # # - One logfile ListCompPinNets.log in the current directory # # - Several output files, one file for each component found (unless requested to be skipped) # Each output file name starts with the component name and describes the number of pins e.g. "U1_has_2104_pins.txt" # # activity messages are printed to the screen and copied to the logfile # ############################################## # Version 0.1 17-Jul-2016: Initial version with most parameters harcoded # Version 0.2 18-Jul-2016: Add command line parameters and description # Version 0.3 23-Jul-2016: Add option to supress style of list of pins in output files # Preserve source netlist file name to show in output i.e. ~Index # Version 1.0 15-Aug-2016 change command line argument to specify configuration file from -i to -c # add flag to enable/disable Index # remember and add line number to Index # if given: read a component file, add type to component file name # Version 2.0 14-Oct-2016 add ability to read dictionaries of pin name/usage to include in output files # Version 2.1 14-Nov-2016 Improve comments, especially header, add print_message # Add UCF file creation # Version 2.2 22-Nov-2016 Add XDC file creation # Version 2.3 23-Nov-2016 Merge lists of net names to skip for UCF and XDC files # Add a list of pin names to skip for UCF and XDC files # Version 2.4 09-Jan-2017: Delay opening the logfile, add timestamp and config file name to logfile name ############################################## app_version = "2.4" app_title = "ListCompPinNets" ############################################## import string import time import sys import os ############################################## # Initialize default values for the name of the configuration file ############################################# # default configuration file name # this name may be overridden on the command line default_config_file_name = "ListCompPinNets.cfg" ############################################## # Initialize default values for the configuration options # The options below may be overwriten in the configuration file ############################################# # The list of netlist file names, as strings, to be read and parsed # The default is no file, i.e. not very useful netfile_list = ( ) # list of files including component type pin name dictionaries called comp_type_pin_name_dict_list = () # path for all output files (must end with a /) # This path may be obsolute or relative, and must already exist. # This does not affect the logfile which is opened # in the local directory before the configuration file is executed. # The default is the local working directory output_dir_name = "./" # option to include the component type pin name, when available include_pin_name = False # option to skip some component prefixes given as a list of strings e.g. "C", "DZ" # The default is to skip nothing skip_comp_prefix = () # option to include the component type pin name, when available include_pin_name = False # warn if a component did not have a dictionary of pin names warn_missing_pin_name_dict = True # option to skip some output list types # The default is to list the pins sorted both by pin number and net name include_sort_by_pin = True include_sort_by_name = True # If a component file is given, the name of the output file will include the component name. # This configuration is optional and the default is to not read a component file component_file_name = "" # a dictionary of component names for which a Xilinx UCF file should be created. ucf_file_dict = {} # a dictionary of component names for which a Xilinx XDC file should be created. xdc_file_dict = {} # a list of Net Name to be skipped from writing to the UCF and XDC file ucfxdc_skip_net_name_lst = () # a list of Comp and Pin Name to be skipped from writing to the UCF and XDC file ucfxdc_skip_comp_pin_ref_lst = () # If this variable is set to 1 each line listing a pin name will show which line of which net file it came from # This configuration is optional and the default is skip generating an index include_index = False # not officially advertized but available debug option # to uppercase all names, the default is inactive force_names_uppercase = False ############################################## # cosmetic names increase code readability :-) ############################################## char_net_delim = "'" char_comment_delim = "#" char_comp_pin_sep = "-" char_space = " " str_net_type = "(NET_TYPE" str_space_40 = " " # elements of array recorded for each pin: net name and source netlist file idx_net_name = 0 idx_pin_name = 1 idx_src_line = 2 idx_src_name = 3 # elements of component type line idx_comp_name = 0 idx_comp_type = 1 tot_comp_items = 8 ################################################################### ################################################################### # function we call in case of exception def show_exc_info ( logfile = None, stop_on_except = 0 ) : #---------------------------- exception_info = sys.exc_info() # retrieve exception info exception_type = exception_info[0] # exception type exception_value = exception_info[1] # exception value exception_at_line = exception_info[2].tb_lineno # traceback item print ' *** exception_type :', exception_type print ' *** exception_value :', exception_value print ' *** exception_at_line :', exception_at_line if ( logfile != None ): logfile.flush ( ) logfile.write ( ' *** exception_type :' + str(exception_type) + '\n' ) logfile.flush ( ) logfile.write ( ' *** exception_value :' + str(exception_value) + '\n' ) logfile.flush ( ) logfile.write ( ' *** exception_at_line :' + str(exception_at_line) + '\n' ) logfile.flush ( ) # del statement is executed left to right # We need to drop reference to traceback # This must be done explicitely (as below) when directly inside except clause # but it would be done implictely when returning from a function like here del [ exception_at_line, exception_value, exception_type, exception_info ] if stop_on_except : raise # stop and get a trace ################################################################### # function to print message to both screen and logfile def print_message ( status = "", app_logfile = None ) : #--------------------- print status if ( app_logfile != None ) : app_logfile.write ( "%s\n" % status ) ################################################################### # read and parse command line arguments #-------------------------------- # There is a default config file name which may be overriden via command line arguments # but we also need to notice when it is overriden config_file_name = default_config_file_name command_line_argument = sys.argv[1:] cmdarg_tot = len ( command_line_argument ) cmdarg_num = 0 while ( cmdarg_num < cmdarg_tot ) : # check for known argument switch and that there will always be a filename after the switch if ( ( command_line_argument[cmdarg_num] not in ( "-c", ) ) or ( cmdarg_num+1 >= cmdarg_tot ) ) : print "\nCommand line error at argument <%s>" % command_line_argument[cmdarg_num] print "Argument Usage: [-c input_resource_filename] \n" sys.exit( 1 ) # alternate input configuration file name elif ( command_line_argument[cmdarg_num] == "-c" ) : config_file_name = command_line_argument[cmdarg_num+1] cmdarg_num = cmdarg_num + 2 #open a logfile #-------------------------------- current_time_bin = time.localtime( time.time() ) current_time_asc = time.asctime ( current_time_bin ) current_time_stamp = time.strftime ( "%Y-%m-%d_%H-%M", # e.g. '2017-01-03_13-09' current_time_bin ) # start logfile name with app name logfile_name = app_title # if not the default add configuration file name (without extension, if present) if ( config_file_name != default_config_file_name ) : logfile_name = "%s_%s" % ( logfile_name, string.split( config_file_name, '.' )[0] ) # add time stamp and extension logfile_name = "%s_%s.log" % ( logfile_name, current_time_stamp ) # logfile name is complete app_logfile = open ( logfile_name, 'w' ) #say hello #-------------------------------- print_message ( " --------------------------" , app_logfile ) print_message ( " %s V%s" % ( app_title, app_version ), app_logfile ) print_message ( " %s" % current_time_asc , app_logfile ) print_message ( " --------------------------" , app_logfile ) print_message ( "\nScreen output copied to Logfile <%s>" % logfile_name , app_logfile ) # ingest the config file and display config parameters #-------------------------------- try: print_message ( "\nReading (i.e. executing) Configuration File <%s>" % config_file_name, app_logfile ) # execute that file execfile ( config_file_name ) # report on what was learned print_message ( " %d Net File(s) will be parsed" % len(netfile_list), app_logfile ) print_message ( " %d Component Type Pin Name Dictionary File(s) will be parsed" % len(comp_type_pin_name_dict_list), app_logfile ) if ( component_file_name != "" ) : print_message ( " Component Type File <%s> will be be parsed" % component_file_name, app_logfile ) else : print_message ( " No Component Type File was provided", app_logfile ) print_message ( " Output Directory will be <%s>" % output_dir_name, app_logfile ) # create it if it does not exist already try : if not os.path.exists( output_dir_name ) : print_message ( " Directory <%s> did not exist, and will be created" % output_dir_name, app_logfile ) os.mkdir( output_dir_name ) except : print_message ( "Failure Creating Output Directory", app_logfile ) show_exc_info ( app_logfile ) status = " Component prefixes skipped are <" for comp_prefix in skip_comp_prefix : status = "%s %s," % ( status, comp_prefix ) status = "%s >" % status print_message ( status, app_logfile ) if include_sort_by_pin : status = " List of pins sorted by pin number will be included" else : status = " List of pins sorted by pin number will not be included" print_message ( status, app_logfile ) if include_sort_by_name : status = " List of pins sorted by net name will be included" else : status = " List of pins sorted by net name will not be included" print_message ( status, app_logfile ) if ( len ( ucf_file_dict ) > 0 ) : for ucf_entry in ucf_file_dict.keys() : print_message ( "UCF File <%s> will be created for component <%s>" % ( ucf_file_dict[ucf_entry], ucf_entry ), app_logfile ) if ( len ( xdc_file_dict ) > 0 ) : for xdc_entry in xdc_file_dict.keys() : print_message ( "XDC File <%s> will be created for component <%s>" % ( xdc_file_dict[xdc_entry], xdc_entry ), app_logfile ) except: print_message ( "Error Reading Config File", app_logfile ) show_exc_info ( app_logfile, stop_on_except = 1 ) # open component file, if given #-------------------------------- # initialize component type dictionary comp_file_dict = dict () # will be filled with all component types found if ( component_file_name != "" ) : # open input trace length file print_message ( "\nReading the Component Type File <%s>" % component_file_name, app_logfile ) inp_comp_file = open ( component_file_name, "r" ) # read component types, but skip first line line_num = 1 for comp_type_line in inp_comp_file.readlines()[1:] : line_num += 1 try : comp_type_line_items = string.split ( comp_type_line ) #print comp_type_line, comp_type_line_items if ( len( comp_type_line_items ) <= idx_comp_type ) : print_message ( " ERROR: unexpected format at line #%d : \n<%s>" % ( line_num, comp_type_line[:-1] ), app_logfile ) elif comp_file_dict.has_key( comp_type_line_items[idx_comp_name] ) : print_message ( " ERROR: duplicate net name found at line #%d : \n<%s>" % ( line_num, comp_type_line[:-1] ), app_logfile ) break comp_name = comp_type_line_items[idx_comp_name] comp_type = comp_type_line_items[idx_comp_type] except : print_message ( " ERROR: parsing problem at line #%d : \n<%s>" % ( line_num, comp_type_line[:-1] ), app_logfile ) show_exc_info ( app_logfile, stop_on_except = 1 ) # undocumented option to force uppercase (like the netlist concatenation script does) if force_names_uppercase : comp_name = comp_name.upper() # add component to dictionary comp_file_dict[ comp_name ] = comp_type # done with component file inp_comp_file.close() # ingest component type pin name dictionary files, if given #-------------------------------- # initialize the dictionary of component types where each entry will be a dictionary of pin names comp_type_dict = { } if ( len ( comp_type_pin_name_dict_list ) != 0 ) : print_message ( "\nReading Component Type Pin Name Dictionary File(s)", app_logfile ) for comp_type_pin_name_dict in comp_type_pin_name_dict_list : print_message ( " Opening Component Type Pin Name File <%s>" % comp_type_pin_name_dict, app_logfile ) # execute that file execfile ( comp_type_pin_name_dict ) print_message ( "\nPin Name Dictionaries were found for", app_logfile ) for comp_type in comp_type_dict : print_message ( " Component Type <%s>" % comp_type, app_logfile ) if type( comp_type_dict[ comp_type ] ) is not dict : print_message ( " Error Pin Names information for Component Type <%s> is not a dictionary" % comp_type, app_logfile ) # open and parse input net list files #-------------------------------- print_message ( "\nReading Input Net File(s)", app_logfile ) # initialize component pin dictionary comp_ref_pin_dict = dict () # will be filled with all components found for inp_netfile in netfile_list : print_message ( " Opening Input Net File <%s>" % inp_netfile, app_logfile ) inp_netlist = open ( inp_netfile, "r" ) # read input file #-------------------------------- line_num = 0 for wrk_net_line in inp_netlist.readlines() : line_num += 1 # drop end of line character wrk_net_line = wrk_net_line[ :-1] # keep copy of original line orig_net_line = wrk_net_line # We only filter NET lines if ( wrk_net_line[:3] == "NET" ) : # There might be a comment at the end of the input line # cut it off now to simplify parsing loc_inp_cmt = string.find ( wrk_net_line, char_comment_delim ) # grab the comment and trim the line if ( loc_inp_cmt > 0 ) : # we remember the comment, without the comment flag, and without the end of line cmt_string = wrk_net_line [ loc_inp_cmt+1 : ] wrk_net_line = wrk_net_line[:loc_inp_cmt] else : cmt_string = "" # There might be a NET_TYPE at the end of the input line # cut it off now to simplify parsing loc_inp_net_type = string.find ( wrk_net_line, str_net_type ) # trim the line if ( loc_inp_net_type > 0 ) : wrk_net_line = wrk_net_line[:loc_inp_net_type] # We need the net name loc_net_start = string.find ( wrk_net_line, char_net_delim ) loc_net_end = string.find ( wrk_net_line[loc_net_start+1:], char_net_delim ) + loc_net_start+1 if ( ( loc_net_start > 0 ) and ( loc_net_end > loc_net_start) ) : # now we have the net name net_name_str = wrk_net_line [ loc_net_start+1 : loc_net_end ] #print "INFO: found net <%s> at line #%d" % ( net_name_str, line_num ) else : net_name_str = "" out_net_line = "%s *** Error *** \n" % ( wrk_net_line[:-1] ) print_message ( " ERROR: no net name found at line #%d" % line_num, app_logfile ) print_message ( " .....: %s " % orig_net_line, app_logfile ) # We have the net name, drop the beginning of the line and the rest should be comp-pin wrk_net_line = wrk_net_line[loc_net_end+1:].lstrip() # guarantee at least one space char at the end of line to aid in recursion wrk_net_line = "%s " % wrk_net_line # now look for component and pin names while len ( wrk_net_line ) > 0 : #print "INFO: parsing <%s>" % wrk_net_line loc_comp_start = 0 loc_comp_end = string.find ( wrk_net_line, char_comp_pin_sep ) comp_ref_str = wrk_net_line[loc_comp_start:loc_comp_end] loc_pin_start = loc_comp_end + 1 loc_pin_end = string.find ( wrk_net_line, char_space ) pin_num_str = wrk_net_line[loc_pin_start:loc_pin_end] # undocumented option to force uppercase (like the netlist concatenation script does) if force_names_uppercase : net_name_str = net_name_str.upper() comp_ref_str = comp_ref_str.upper() pin_num_str = pin_num_str.upper() pin_name = "" if include_pin_name : # try to retrieve pin name if known if comp_file_dict.has_key( comp_ref_str ) : comp_type = comp_file_dict[ comp_ref_str ] if comp_type_dict.has_key( comp_type ) : if comp_type_dict[ comp_type ].has_key( pin_num_str ) : pin_name = comp_type_dict[ comp_type ][ pin_num_str ] else : print_message ( " WARNING: pin number <%s> was not included in dictionary for component type <%s> at line #%d" \ % ( pin_num_str, comp_type, line_num ), app_logfile ) # create new entry if we have not already met this component if not comp_ref_pin_dict.has_key ( comp_ref_str ) : comp_ref_pin_dict[comp_ref_str] = dict () # verify that that we have not met this pin before if comp_ref_pin_dict[comp_ref_str].has_key ( pin_num_str ) : print_message ( " ERROR: same pin had already been assigned a net name, found at line #%d" % line_num, app_logfile ) print_message ( " .....: %s " % orig_net_line, app_logfile ) else : # save the line number and file name if we need to include it later line_net_file = "" name_net_file = "" if include_index : line_net_file = "from line %5d" % line_num name_net_file = "of %s" % os.path.basename ( inp_netfile ) # element order below must match definition of idx_net_name, idx_pin_name, idx_src_line, idx_src_name comp_ref_pin_dict[comp_ref_str][pin_num_str] = ( net_name_str, pin_name, line_net_file, name_net_file ) # remove this comp+pin and look for more wrk_net_line = wrk_net_line[loc_pin_end+1:].lstrip() # done with this input file #-------------------------- inp_netlist.close() # now write out all component dictionary entries #----------------------------------------------- print_message ( "\nWriting Component Pin Net Files", app_logfile ) absolute_output_dir_name = os.path.abspath( output_dir_name ) if not os.path.exists( absolute_output_dir_name ): print_message ( "\n Output directory does not exist, please create it:", app_logfile ) print_message ( " <%s>\n" % absolute_output_dir_name, app_logfile ) sys.exit(1) tot_comp = len ( comp_ref_pin_dict ) tot_pin = 0 # scan all component entries (sorted to make logfile more useful) for comp_entry in sorted ( comp_ref_pin_dict ) : #print "Component is <%s>" % comp_entry # determine component prefix if comp_entry[-1:].isdigit() : # is there at least one digit at the end loc_index = 1 while not comp_entry[loc_index:].isdigit() : loc_index += 1 comp_prefix = comp_entry[:loc_index] else : # there was no component number comp_prefix = comp_entry # skip output files for certain prefixes #print "Component Prefix is <%s>" % comp_prefix if ( ( comp_prefix.upper() not in skip_comp_prefix ) and ( comp_entry.upper() not in skip_comp_prefix ) ) : # create file name, starting with the component name and pin count comp_file_name = "%s%s_has_%d_pins" % ( output_dir_name, comp_entry, len ( comp_ref_pin_dict[ comp_entry ] ) ) # if available, include component type in file name comp_type = "" if comp_file_dict.has_key( comp_entry ) : comp_type = comp_file_dict[ comp_entry ] comp_file_name = "%s_is_%s" % ( comp_file_name, comp_type ) elif ( component_file_name != "" ) : # only complain if we were given a component file print_message ( "WARNING: component <%s> not found in component file" % comp_entry, app_logfile ) # done with output component file name comp_file_name = "%s.txt" % comp_file_name # open this new file comp_file = open ( comp_file_name, 'w' ) # write total number of pins status = " Found %d pins for %s" % ( len ( comp_ref_pin_dict[comp_entry] ) , comp_entry ) # and, if available, include component type if ( comp_type != "" ) : status = "%s which is of type %s" % ( status, comp_type ) comp_file.write ( "%s\n" % status ) print_message ( status, app_logfile ) # if requested, complain about missing pin name dictionary if ( include_pin_name # only when we include pin names and warn_missing_pin_name_dict # only when we were told to warn and comp_file_dict.has_key( comp_entry ) # only if we haven't already complained about missing type and not comp_type_dict.has_key( comp_type ) ) :# and when there is no entry for this component type print_message ( " WARNING: No pin dictionary available for comp type <%s>" % comp_type, app_logfile ) # now write list of pins and list of nets if include_sort_by_pin : # First (try to) sort pins numerically (padding up pin name to help alphabetic order at least for pure decimal) status = "\n------------------------------------------------------\nPins sorted by Pin Name\n" comp_file.write ( "%s\n" % status ) for pin_entry in sorted ( comp_ref_pin_dict[comp_entry].iteritems(), key=lambda x:"%s%s" % ( "000000"[ :6-len(x[0]) ], x[0] ) ) : #print pin_entry pin_line = "%5s = %s %s %s %s %s %s" % ( pin_entry[0], pin_entry[1][idx_net_name], str_space_40[ : 40 -len( pin_entry[1][idx_net_name] ) ], pin_entry[1][idx_pin_name], str_space_40[ : 35 -len( pin_entry[1][idx_pin_name] ) ], pin_entry[1][idx_src_line], pin_entry[1][idx_src_name] ) # there may be lots of trailing spaces, trim it comp_file.write ( "%s\n" % pin_line.rstrip() ) if include_sort_by_name : # Also sort pins by net names status = "\n------------------------------------------------------\nPins sorted by Net Name\n" comp_file.write ( "%s\n" % status ) for pin_entry in sorted ( comp_ref_pin_dict[comp_entry].iteritems(), key=lambda x:x[1] ) : #print pin_entry pin_line = "%5s = %s %s %s %s %s %s" % ( pin_entry[0], pin_entry[1][idx_net_name], str_space_40[ : 40 -len( pin_entry[1][idx_net_name] ) ], pin_entry[1][idx_pin_name], str_space_40[ : 35 -len( pin_entry[1][idx_pin_name] ) ], pin_entry[1][idx_src_line], pin_entry[1][idx_src_name] ) # there may be lots of trailing spaces, trim it comp_file.write ( "%s\n" % pin_line.rstrip() ) # done with this file comp_file.close() # keep track of total number of pins, # even if no file was created tot_pin += len ( comp_ref_pin_dict[comp_entry] ) # write total number of components and pins print_message ( "\nFound a Total of %d Components and %d Pins in %d Net files\n" \ % ( tot_comp , tot_pin, len(netfile_list) ), app_logfile ) # now ceate any requested User Constraint Files #---------------------------------------------- # create UCF file(s) if ( len ( ucf_file_dict ) > 0 ) : for ucf_entry in ucf_file_dict.keys() : ucf_file_name = ucf_file_dict[ucf_entry] print_message ( "Writing UCF File <%s> for component <%s>" % ( ucf_file_name, ucf_entry ), app_logfile ) if not comp_ref_pin_dict.has_key ( ucf_entry ) : print_message ( "ERROR: No component found by this name ", app_logfile ) else : ucf_file = open ( ucf_file_name, "w" ) ucf_file.write ( "//\n// File created by %s V%s on %s \n//\n" % ( app_title, app_version, current_time_asc ) ) for pin_entry in sorted ( comp_ref_pin_dict[ucf_entry].iteritems(), key=lambda x:x[1] ) : net_name = pin_entry[1][idx_net_name] net_name_padding = str_space_40[: 40 -len( net_name ) ] pin_name = pin_entry[1][idx_pin_name] pin_num_str = pin_entry[0] comp_pin_ref = "%s-%s" % ( ucf_entry, pin_num_str ) if ( ( net_name not in ucfxdc_skip_net_name_lst ) and ( comp_pin_ref not in ucfxdc_skip_comp_pin_ref_lst ) ) : ucf_file.write ( '\n// %s\nNET "%s" %s LOC = "%s";\n' % ( pin_name, net_name, net_name_padding, pin_num_str ) ) ucf_file.close () # create XDC file(s) if ( len ( xdc_file_dict ) > 0 ) : for xdc_entry in xdc_file_dict.keys() : xdc_file_name = xdc_file_dict[xdc_entry] print_message ( "Writing XDC File <%s> for component <%s>" % ( xdc_file_name, xdc_entry ), app_logfile ) if not comp_ref_pin_dict.has_key ( xdc_entry ) : print_message ( "ERROR: No component found by this name ", app_logfile ) else : xdc_file = open ( xdc_file_name, "w" ) xdc_file.write ( "//\n// File created by %s V%s on %s \n//\n" % ( app_title, app_version, current_time_asc ) ) for pin_entry in sorted ( comp_ref_pin_dict[xdc_entry].iteritems(), key=lambda x:x[1] ) : net_name = pin_entry[1][idx_net_name] pin_name = pin_entry[1][idx_pin_name] pin_num_str = pin_entry[0] pin_num_padding = str_space_40[: 5 -len( pin_num_str ) ] comp_pin_ref = "%s-%s" % ( xdc_entry, pin_num_str ) if ( ( net_name not in ucfxdc_skip_net_name_lst ) and ( comp_pin_ref not in ucfxdc_skip_comp_pin_ref_lst ) ) : xdc_file.write ( '\n# %s\nset_property PACKAGE_PIN %s%s [get_ports "%s"] ;\n' % ( pin_name, pin_num_padding, pin_num_str, net_name ) ) xdc_file.close () # Done #-------------------------------- print_message ( "\nDone\n", app_logfile )