diff --git a/openfpga_flow/misc/modelsim_proc.tcl b/openfpga_flow/misc/modelsim_proc.tcl index cede56af4..69972b764 100644 --- a/openfpga_flow/misc/modelsim_proc.tcl +++ b/openfpga_flow/misc/modelsim_proc.tcl @@ -47,7 +47,7 @@ proc top_create_new_project {projectname verilog_files modelsim_path simtime uni #Start the simulation vsim $projectname.$top_tb -voptargs=+acc #Add the waves - add_waves top_tb + add_waves $top_tb #run the simulation runsim $simtime $unit #Fit the window view diff --git a/openfpga_flow/scripts/run_modelsim.py b/openfpga_flow/scripts/run_modelsim.py index 0ddbe118c..2f4ac5fc4 100644 --- a/openfpga_flow/scripts/run_modelsim.py +++ b/openfpga_flow/scripts/run_modelsim.py @@ -1,12 +1,12 @@ from string import Template import sys import os -import pprint +import re +import glob import argparse import subprocess import logging -from pprint import pprint -from configparser import ConfigParser +from configparser import ConfigParser, ExtendedInterpolation # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Configure logging system @@ -20,7 +20,8 @@ logger = logging.getLogger('Modelsim_run_log') # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = parser = argparse.ArgumentParser() parser.add_argument('files', nargs='+', - help="Pass SimulationDeckInfo generated by OpenFPGA flow") + help="Pass SimulationDeckInfo generated by OpenFPGA flow" + + " or pass taskname ") parser.add_argument('--modelsim_proc_tmpl', type=str, help="Modelsim proc template file") parser.add_argument('--modelsim_runsim_tmpl', type=str, @@ -36,9 +37,32 @@ parser.add_argument('--modelsim_ini', type=str, help="Skip any confirmation") parser.add_argument('--skip_prompt', action='store_true', help='Skip any confirmation') +parser.add_argument('--ini_filename', type=str, + default="simulation_deck_info.ini", + help='default INI filename in in fun dir') args = parser.parse_args() -# Consider default formality script template +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Read script configuration file +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +task_script_dir = os.path.dirname(os.path.abspath(__file__)) +script_env_vars = ({"PATH": { + "OPENFPGA_FLOW_PATH": task_script_dir, + "ARCH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "arch"), + "BENCH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "benchmarks"), + "TECH_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "tech"), + "SPICENETLIST_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "SpiceNetlists"), + "VERILOG_PATH": os.path.join("${PATH:OPENFPGA_PATH}", "VerilogNetlists"), + "OPENFPGA_PATH": os.path.abspath(os.path.join(task_script_dir, os.pardir, + os.pardir))}}) +config = ConfigParser(interpolation=ExtendedInterpolation()) +config.read_dict(script_env_vars) +config.read_file(open(os.path.join(task_script_dir, 'run_fpga_task.conf'))) +gc = config["GENERAL CONFIGURATION"] + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Load default templates for modelsim +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = task_script_dir = os.path.dirname(os.path.abspath(__file__)) if not args.modelsim_proc_tmpl: args.modelsim_proc_tmpl = os.path.join(task_script_dir, os.pardir, @@ -52,7 +76,49 @@ args.modelsim_runsim_tmpl = os.path.abspath(args.modelsim_runsim_tmpl) def main(): - for eachFile in args.files: + if os.path.isfile(args.files[0]): + run_modelsim(args.files) + else: + # Check if task directory exists and consistent + taskname = args.files[0] + task_run = "latest" + if len(args.files) > 1: + task_run = f"run{int(args.files[1]):03}" + + temp_dir = os.path.join(gc["task_dir"], taskname) + if not os.path.isdir(temp_dir): + clean_up_and_exit("Task directory [%s] not found" % temp_dir) + temp_dir = os.path.join(gc["task_dir"], taskname, task_run) + if not os.path.isdir(temp_dir): + clean_up_and_exit("Task run directory [%s] not found" % temp_dir) + + logfile = os.path.join(gc["task_dir"], taskname, task_run, "*.log") + logfiles = glob.glob(logfile) + if not len(logfiles): + clean_up_and_exit("No successful run found in [%s]" % temp_dir) + + task_ini_files = [] + for eachfile in logfiles: + with open(eachfile) as fp: + run_dir = [re.findall(r'^INFO.*Run directory : (.*)$', line) + for line in open(eachfile)] + run_dir = filter(bool, run_dir) + for each_run in run_dir: + INIfile = os.path.join(each_run[0], args.ini_filename) + if os.path.isfile(INIfile): + task_ini_files.append(INIfile) + logger.info(f"Found {len(task_ini_files)} INI files") + run_modelsim(task_ini_files) + + +def clean_up_and_exit(msg): + logger.error(msg) + logger.error("Exiting . . . . . .") + exit(1) + + +def run_modelsim(files): + for eachFile in files: eachFile = os.path.abspath(eachFile) pDir = os.path.dirname(eachFile) os.chdir(pDir) @@ -111,10 +177,10 @@ def main(): # Execute modelsim if args.run_sim: os.chdir(args.modelsim_run_dir) - print(args.modelsim_run_dir) modelsim_run_cmd = ["vsim", "-c", "-do", runsim_filename] - run_command("ModelSim Run", "modelsim_run.log", - modelsim_run_cmd) + out = run_command("ModelSim Run", "modelsim_run.log", + modelsim_run_cmd) + logger.info(re.findall(r"(.*Errors.*Warning.*)", out)) else: logger.info("Created runsim and proc files") logger.info(f"runsim_filename {runsim_filename}")