mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			108 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/python3
 | 
						|
 | 
						|
# iterelf
 | 
						|
# David_Harris@hmc.edu and Rose Thompson 7/3/2024
 | 
						|
# Run wsim on all the ELF files in a directory in parallel in lockstep
 | 
						|
 | 
						|
 | 
						|
import argparse
 | 
						|
import os
 | 
						|
import multiprocessing
 | 
						|
from multiprocessing import Pool, TimeoutError
 | 
						|
TIMEOUT_DUR = 60  # 1` minute
 | 
						|
 | 
						|
class bcolors:
 | 
						|
    HEADER = '\033[95m'
 | 
						|
    OKBLUE = '\033[94m'
 | 
						|
    OKCYAN = '\033[96m'
 | 
						|
    OKGREEN = '\033[92m'
 | 
						|
    WARNING = '\033[93m'
 | 
						|
    FAIL = '\033[91m'
 | 
						|
    ENDC = '\033[0m'
 | 
						|
    BOLD = '\033[1m'
 | 
						|
    UNDERLINE = '\033[4m'
 | 
						|
 | 
						|
def search_log_for_mismatches(logfile):
 | 
						|
    """Search through the given log file for text, returning True if it is found or False if it is not"""
 | 
						|
    grepwarn = "grep -H Warning: " + logfile
 | 
						|
    os.system(grepwarn)
 | 
						|
    greperr = "grep -H Error: " + logfile
 | 
						|
    os.system(greperr)
 | 
						|
    grepcmd = "grep -a -e 'Mismatches            : 0' '%s' > /dev/null" % logfile
 | 
						|
#    print("  search_log_for_text invoking %s" % grepcmd)
 | 
						|
    return os.system(grepcmd) == 0
 | 
						|
 | 
						|
def run_test_case(elf):
 | 
						|
    """Run the given test case, and return 0 if the test suceeds and 1 if it fails"""
 | 
						|
    WALLY = os.environ.get('WALLY')
 | 
						|
    fields = elf.rsplit('/', 3)
 | 
						|
    if (fields[2] == "ref"):
 | 
						|
        shortelf = fields[1] + "_" + fields[3]
 | 
						|
    else:
 | 
						|
        shortelf = fields[2] + "_" + fields[3]
 | 
						|
#    shortelf = fields[1] + "_" + fields[2]
 | 
						|
    logfile = WALLY + "/sim/" + args.sim + "/logs/" + shortelf + ".log"
 | 
						|
    cmd = "wsim " + args.config + " " + shortelf + " --elf " + elf + " --sim " + args.sim + " --lockstep > " + logfile   # add coveerage flags if necessary
 | 
						|
#    print("cmd = " + cmd)
 | 
						|
    os.system(cmd)
 | 
						|
    if search_log_for_mismatches(logfile):
 | 
						|
        print(f"{bcolors.OKGREEN}%s: Success{bcolors.ENDC}" % (cmd))
 | 
						|
        return 0
 | 
						|
    elif("WALLY-cbom-01" in elf):
 | 
						|
        # Remove this when CBO instructions are modeled in ImperasDV
 | 
						|
        print(f"{bcolors.OKCYAN}%s: Expected mismatch because ImperasDV does not yet model cache for CBO instructions {bcolors.ENDC}" % (cmd))
 | 
						|
        return 0
 | 
						|
    else:
 | 
						|
        print(f"{bcolors.FAIL}%s: Failures detected in output{bcolors.ENDC}" % (cmd))
 | 
						|
        print("  Check %s" % logfile)
 | 
						|
        return 1
 | 
						|
 | 
						|
##################################
 | 
						|
# Main body
 | 
						|
##################################
 | 
						|
 | 
						|
# Parse arguments
 | 
						|
parser = argparse.ArgumentParser()
 | 
						|
parser.add_argument("dir", help="Configuration file")
 | 
						|
parser.add_argument("--config", help="Configuration", default="rv64gc")
 | 
						|
parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "vcs"], default="questa")
 | 
						|
parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true")
 | 
						|
parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true")
 | 
						|
parser.add_argument("--exclude", help="Exclude files with this sufix", default="my.elf")
 | 
						|
args = parser.parse_args()
 | 
						|
 | 
						|
# find all ELF files in directory
 | 
						|
 | 
						|
ElfList = []
 | 
						|
if (os.path.isdir(args.dir)):
 | 
						|
    DirectorMode = 1
 | 
						|
    for dirpath, dirnames, filenames in os.walk(os.path.abspath(args.dir)):
 | 
						|
        for file in filenames:
 | 
						|
            if (file.endswith("elf") and not file.endswith(args.exclude)):
 | 
						|
                ElfList.append(os.path.join(dirpath, file))
 | 
						|
else:
 | 
						|
    print(args.dir + " is not a directory")
 | 
						|
    exit(1)
 | 
						|
#print(ElfList)
 | 
						|
 | 
						|
# spawn parallel wsim jobs for each ELF file
 | 
						|
 | 
						|
ImperasDVLicenseCount = 8
 | 
						|
with Pool(processes=min(len(ElfList),multiprocessing.cpu_count(), ImperasDVLicenseCount)) as pool:
 | 
						|
    num_fail = 0
 | 
						|
    results = {}
 | 
						|
    for elf in ElfList:
 | 
						|
        results[elf] = pool.apply_async(run_test_case,(elf,))
 | 
						|
    for (elf,result) in results.items():
 | 
						|
        try:
 | 
						|
            num_fail+=result.get(timeout=TIMEOUT_DUR)
 | 
						|
        except TimeoutError:
 | 
						|
            num_fail+=1
 | 
						|
            print(f"{bcolors.FAIL}%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (elf, TIMEOUT_DUR))
 | 
						|
 | 
						|
if (num_fail == 0):
 | 
						|
    print(f"{bcolors.OKGREEN}SUCCESS! All tests ran without failures{bcolors.ENDC}")
 | 
						|
else:
 | 
						|
    print(f"{bcolors.FAIL}Completed %d tests with %d failures{bcolors.ENDC}" % (len(ElfList), num_fail))
 | 
						|
 |