Skip to content
Snippets Groups Projects
filelist_compile.py 13.3 KiB
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)
//
dam1n19's avatar
dam1n19 committed
// Copyright 2021-3, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 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()
    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
                    # 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): 
                        # 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))
            elif line_list[0].startswith("+incdir+"):
                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 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") + " ]")
dam1n19's avatar
dam1n19 committed
                        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"))
                            else:
                                compiled_filelist.append("set search_path " + str(line_list[0].lstrip("+incdir+")).replace("$","$env"))
dam1n19's avatar
dam1n19 committed
                            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"))
                            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.tcl == True:
        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"
    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'
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.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("-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)