Newer
Older
#!/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)
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Abstract : Verilog Command File with expanded system variables
//-----------------------------------------------------------------------------
"""
def env_var_substitute(path, tcl=False):
# Interpret the path and remove brackets from path
if tcl == False:
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()
# 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:
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):
# 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))
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))
else:
compiled_filelist.append("read_verilog " + str(line_list[1])+"/"+str(file).replace("$","$env"))
else:
compiled_filelist.append(line_list[1]+"/"+str(file))
if args.absolute == True:
incdirs.append(env_var_substitute(line_list[0].lstrip("+incdir+")))
else:
incdirs.append(line_list[0].lstrip("+incdir+"))
if args.absolute == 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"))
else:
compiled_filelist.append("set search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env"))
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"))
else:
compiled_filelist.append("set search_path [ concat $search_path " + str(env_var_substitute(line_list[0].lstrip("+incdir+"), tcl=True)).replace("$","$env") + " ]")
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"))
else:
compiled_filelist.append("set search_path " + str(line_list[0].lstrip("+incdir+")).replace("$","$env"))
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"))
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:
for file in os.listdir(env_var_substitute(line_list[0].lstrip("+incdir+"))):
if file.endswith(verilog_extensions):
# 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:
hdl_files.append(str(env_var_substitute(line_list[0], tcl=True)).replace("$","$env"))
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 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 == False:
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)
else:
if hdl_files[0].endswith(".sv"):
temp_str = f'read_hdl -language sv '
else:
temp_str = f'read_hdl '
for file in hdl_files:
temp_str += file + " "
compiled_filelist.append(temp_str)
return compiled_filelist, first, incdirs
def incdir_compile(args, incdirs):
temp_str = ""
if args.genus == 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"
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'
def filelist_compile(args):
input_filelist = args.filelist
output_filelist = args.output
print("Compiling Filelist")
# 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.tcl == True:
# 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("-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("-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)