#!/usr/bin/env python3 #------------------------------------------------------------------------------------ # Verilog Filelist compilation script # A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. # # Contributors # # David Mapstone (d.a.mapstone@soton.ac.uk) # Copyright (c) 2023, SoC Labs (www.soclabs.org) #------------------------------------------------------------------------------------ import argparse import os # Files with these extensions are included in compiled filelists verilog_extensions = (".v", ".sv", ".vh") # Exclude paths including these strings filelist_exclusions = ["cortex","pl230"] filelist_header = """//----------------------------------------------------------------------------- // AUTOGENERATED: Compiled Filelist // A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. // // Contributors // // David Mapstone (d.a.mapstone@soton.ac.uk) // // Copyright 2021-3, SoC Labs (www.soclabs.org) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Abstract : Verilog Command File with expanded system variables //----------------------------------------------------------------------------- """ def file_contains_module(f): if 'module' in open(f).read(): return True else: print('### -y strip: no module in ' + f) return False def env_var_substitute(path, tcl=False, synthesis=False): # Interpret the path and remove brackets from path if tcl == False: sub_path = path.translate(str.maketrans('', '', '()')) elif synthesis ==True: sub_path = path.translate(str.maketrans('', '', '()')) else: sub_path = path # Expand environment variables in Path sub_path = os.path.expandvars(sub_path) return sub_path def read_list(filelist, first, incdirs, args): # Create Filelist List Structure compiled_filelist = [] # Open Filelist and Read Lines f = open(filelist, "r") filelines = f.readlines() f.close() hdl_files = [] # Remove Black Lines from list filelines = [x.rstrip("\n") for x in filelines] filelines = [x for x in filelines if x != ""] # Iterate over list and process for line in filelines: # Remove whitespace and split line into arguments line_list = line.strip().split() # Check Line isn't a comment if not line_list[0].startswith("//"): # If line is a reference to another filelist if line_list[0] == "-f": # Recursively call this function and append list to this compiled Filelist if any(ext in line_list[1] for ext in filelist_exclusions) and args.exclude == True: # print(line_list[1]+" is in the exclusions list") pass else: # print(line_list[1]) temp_list, first, incdirs = read_list(env_var_substitute(line_list[1]), first, incdirs, args) compiled_filelist += temp_list elif line_list[0] == "-y": # Append to filelist for file in os.listdir(env_var_substitute(line_list[1])): if (file.endswith(verilog_extensions) and file_contains_module(str(env_var_substitute(line_list[1], tcl=False)).replace("$","$env")+"/"+str(file))): # Append to filelist if args.absolute == True: if args.tcl == True: if args.genus == True: if file.endswith(".sv"): compiled_filelist.append("read_hdl -language sv " + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) else: compiled_filelist.append("read_hdl " + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) elif args.synthesis ==True: compiled_filelist.append("cp -p " + str(env_var_substitute((line_list[1])+"/"+str(file), tcl=True, synthesis=True))) elif args.makefile == True: compiled_filelist.append("VERILOG_SOURCES += " + str(env_var_substitute((line_list[1])+"/"+str(file), synthesis=True))) else: compiled_filelist.append("read_verilog " + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) else: compiled_filelist.append(env_var_substitute(line_list[1])+"/"+str(file)) else: if args.tcl == True: if args.genus == True: if file.endswith(".sv"): compiled_filelist.append("read_hdl -language sv " + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) else: compiled_filelist.append("read_hdl " + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) elif args.synthesis == True: compiled_filelist.append("cp -p" + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) elif args.makefile == True: compiled_filelist.append("VERILOG_SOURCES += " + str(line_list[1]).replace("$","$env")+"/"+str(file)) else: compiled_filelist.append("read_verilog " + str(env_var_substitute(line_list[1], tcl=True)).replace("$","$env")+"/"+str(file)) else: if (file.endswith(".v") or (file.endswith(".sv") and (args.html == False))): compiled_filelist.append(line_list[1]+"/"+str(file)) elif line_list[0].startswith("+incdir+"): # Append to filelist if args.absolute == True: incdirs.append(env_var_substitute(line_list[0].lstrip("+incdir+"))) else: incdirs.append(line_list[0].lstrip("+incdir+")) if args.tcl == True: if args.absolute == True: if first == True: if args.genus == True: compiled_filelist.append("set_db init_hdl_search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env")) elif args.synthesis == True: pass else: compiled_filelist.append("set search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env")) first = False else: if args.genus == True: compiled_filelist.append("set_db init_hdl_search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env")) elif args.synthesis == True: pass else: compiled_filelist.append("set search_path [ concat $search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env") + " ]") else: if first == True: if args.genus == True: compiled_filelist.append("set_db init_hdl_search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env")) elif args.synthesis == True: pass else: compiled_filelist.append("set search_path " + str(line_list[0].lstrip("+incdir+")).replace("$","$env")) first = False else: if args.genus == True: compiled_filelist.append("set_db init_hdl_search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env")) elif args.synthesis == True: pass else: compiled_filelist.append("set search_path [ concat $search_path " + str(line_list[0].lstrip("+incdir+")).replace("$","$env") + " ]") # elif args.makefile == True: # if args.absolute == True: # if first == True: # compiled_filelist.append("set search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env")) # first = False # else: # compiled_filelist.append("set search_path [ concat $search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env") + " ]") # else: # if first == True: # compiled_filelist.append("set search_path " + str(line_list[0].lstrip("+incdir+")).replace("$","$env")) # first = False # else: # compiled_filelist.append("set search_path [ concat $search_path " + str(line_list[0].lstrip("+incdir+")).replace("$","$env") + " ]") ##elif args.makefile == False: elif ((args.makefile == False) and (args.vfiles == False)): for file in os.listdir(env_var_substitute(line_list[0].lstrip("+incdir+"))): if (file.endswith(".v") or (file.endswith(".sv") and (args.html == False))): # Append to filelist if args.absolute == True: compiled_filelist.append(env_var_substitute(line_list[0].lstrip("+incdir+"))+"/"+str(file)) else: compiled_filelist.append(line_list[0].lstrip("+incdir+")+"/"+str(file)) # If file list a verilog file elif line_list[0].endswith(verilog_extensions): # Append to filelist if args.tcl == True: if args.absolute == True: if args.synthesis == True: hdl_files.append(str(env_var_substitute(line_list[0], synthesis=True))) else: hdl_files.append(str(env_var_substitute(line_list[0], tcl=True)).replace("$","$env")) else: if args.synthesis == True: hdl_files.append(str(line_list[0])) else: hdl_files.append(str(line_list[0]).replace("$","$env")) elif args.makefile == True: if args.absolute == True: compiled_filelist.append("VERILOG_SOURCES += " + str(env_var_substitute(line_list[0], tcl=True))) else: compiled_filelist.append("VERILOG_SOURCES += " + str(line_list[0])) else: if (line_list[0].endswith(".v") or (line_list[0].endswith(".sv") and (args.html == False))): if args.absolute == True: compiled_filelist.append(env_var_substitute(line_list[0])) else: compiled_filelist.append(line_list[0]) if len(hdl_files) > 0: # temp_str = 'add_files -norecurse -scan_for_includes "' if args.genus == True: if hdl_files[0].endswith(".sv"): temp_str = f'read_hdl -define POWER_PINS -language sv ' else: temp_str = f'read_hdl -define POWER_PINS ' for file in hdl_files: temp_str += file + " " compiled_filelist.append(temp_str) elif args.synthesis ==True: temp_str="" for file in hdl_files: temp_str += f'cp -p {file} {args.rtldir}/\n' compiled_filelist.append(temp_str) else: temp_str = f'add_files -norecurse -force -copy_to {args.rtldir} "' for file in hdl_files: temp_str += file + " " temp_str += '"' compiled_filelist.append(temp_str) return compiled_filelist, first, incdirs def incdir_compile(args, incdirs): temp_str = "" if args.tcl == True: if args.genus == False: if args.synthesis == False: if len(incdirs) > 0: temp_str = 'set_property include_dirs "' for directory in incdirs: temp_dir = str(directory).replace("$","$env") temp_str += " " + temp_dir temp_str += '" [current_fileset]' elif args.makefile == True: if len(incdirs) > 0: for directory in incdirs: temp_str += "EXTRA_ARGS += +incdir+" + str(directory) + "\n" elif args.vfiles == True: if len(incdirs) > 0: for directory in incdirs: temp_str += "+incdir+" + str(directory) + "\n" return temp_str def defines_compile(args): temp_str = "" if len(args.defines) > 0: for define in args.defines: temp_str += 'set_property generic "' + str(define) + '" [current_fileset]\n' temp_str += 'set_property verilog_define "' + str(define) + '" [current_fileset]\n' return temp_str def filelist_compile(args): input_filelist = args.filelist output_filelist = args.output print("Compiling Filelist") incdirs = [] # Read in filelist and add newlines to paths filelist, first, incdirs = read_list(input_filelist, True, incdirs, args) filelist = [x+"\n" for x in filelist] # Create string of all paths to write out filelist_str = filelist_header if (args.tcl == False and args.makefile == False) else filelist_header.replace("//","#") if args.synthesis == True: filelist_str = "#!/bin/bash \n" + filelist_str if args.tcl == True: if args.genus==False: # filelist_str += incdir_compile(args, incdirs) + "\n" filelist_str += defines_compile(args) for path in filelist: filelist_str += path filelist_str += incdir_compile(args, incdirs) + "\n" # filelist_str += defines_compile(args) # Write out output filelist f_outlist = open(output_filelist, "w") f_outlist.write(filelist_str) f_outlist.close() if __name__ == "__main__": # Capture Arguments from Command Line parser = argparse.ArgumentParser(description='Compiles Filelist to Read') parser.add_argument("-f", "--filelist", type=str, help="Input Filelist to Read") parser.add_argument("-o", "--output", type=str, help="Output Filelist location") parser.add_argument("-e", "--exclude", action='store_true', help="Exclude filists including these strings") parser.add_argument("-t", "--tcl", action='store_true', help="Generate a TCL Script") parser.add_argument("-g", "--genus", action = 'store_true', help="Generate TCL script for genus") parser.add_argument("-s", "--synthesis", action = 'store_true', help ="Generate bash script for copying flist to synthesis") parser.add_argument("-m", "--makefile", action='store_true', help="Generate a Makefile RTL Sources File") parser.add_argument("-a", "--absolute", action='store_true', help="Substitute environment Variables with Absolute Path") parser.add_argument("-v", "--vfiles", action='store_true', help="Generate a vc filelist") parser.add_argument("-n", "--html", action='store_true', help="No '.sv' - strip files as HTML wont render") parser.add_argument("-r", "--rtldir", type=str, help="Directory where RTL Source will be copied to in TCL mode") parser.add_argument('-d', '--defines', nargs='+', default=[]) args = parser.parse_args() filelist_compile(args)