from string import Template import sys import os import pprint import argparse import subprocess import logging from pprint import pprint from configparser import ConfigParser # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Configure logging system # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = logging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(levelname)s (%(threadName)10s) - %(message)s') logger = logging.getLogger('Modelsim_run_log') # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Parse commandline arguments # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = parser = argparse.ArgumentParser() parser.add_argument('files', nargs='+', help="Pass SimulationDeckInfo generated by OpenFPGA flow") parser.add_argument('--modelsim_proc_tmpl', type=str, help="Modelsim proc template file") parser.add_argument('--modelsim_runsim_tmpl', type=str, help="Modelsim runsim template file") parser.add_argument('--run_sim', action="store_true", help="Execute generated script in formality") parser.add_argument('--modelsim_proj_dir', help="Provide modelsim project directory") parser.add_argument('--modelsim_proj_name', help="Provide modelsim project name") parser.add_argument('--modelsim_ini', type=str, default="/uusoc/facility/cad_tools/Mentor/modelsim10.7b/modeltech/modelsim.ini", help="Skip any confirmation") parser.add_argument('--skip_prompt', action='store_true', help='Skip any confirmation') args = parser.parse_args() # Consider default formality script template 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, "misc", "modelsim_proc.tcl") if not args.modelsim_runsim_tmpl: args.modelsim_runsim_tmpl = os.path.join(task_script_dir, os.pardir, "misc", "modelsim_runsim.tcl") args.modelsim_proc_tmpl = os.path.abspath(args.modelsim_proc_tmpl) args.modelsim_runsim_tmpl = os.path.abspath(args.modelsim_runsim_tmpl) def main(): for eachFile in args.files: eachFile = os.path.abspath(eachFile) pDir = os.path.dirname(eachFile) os.chdir(pDir) config = ConfigParser() config.read(eachFile) config = config["SIMULATION_DECK"] # Resolve project Modelsim project path if not args.modelsim_proj_dir: args.modelsim_run_dir = os.path.dirname(os.path.abspath(eachFile)) args.modelsim_proj_dir = os.path.join( args.modelsim_run_dir, "MMSIM2") logger.info(f"Modelsim project dir not provide " + f"using default {args.modelsim_proj_dir} directory") if not args.skip_prompt: input("Press Enter to continue, Ctrl+C to abort") args.modelsim_proj_dir = os.path.abspath(args.modelsim_proj_dir) config["MODELSIM_PROJ_DIR"] = args.modelsim_proj_dir if not os.path.exists(args.modelsim_proj_dir): os.makedirs(args.modelsim_proj_dir) # Resolve Modelsim Project name if not args.modelsim_proj_name: args.modelsim_proj_name = config["BENCHMARK"] + "_MMSIM" logger.info(f"Modelsim project name not provide " + f"using default {args.modelsim_proj_name} directory") if not args.skip_prompt: input("Press Enter to continue, Ctrl+C to abort") config["MODELSIM_PROJ_NAME"] = args.modelsim_proj_name config["MODELSIM_INI"] = args.modelsim_ini # Modify the variables in config file here config["TOP_TB"] = os.path.splitext(config["TOP_TB"])[0] # pass # Write final template file # Write runsim file tmpl = Template(open(args.modelsim_runsim_tmpl, encoding='utf-8').read()) runsim_filename = os.path.join(args.modelsim_proj_dir, "%s_runsim.tcl" % config['BENCHMARK']) logger.info(f"Creating tcl script at : {runsim_filename}") with open(runsim_filename, 'w', encoding='utf-8') as tclout: tclout.write(tmpl.substitute(config)) # Write proc file proc_filename = os.path.join(args.modelsim_proj_dir, "%s_autocheck_proc.tcl" % config['BENCHMARK']) logger.info(f"Creating tcl script at : {proc_filename}") with open(proc_filename, 'w', encoding='utf-8') as tclout: tclout.write(open(args.modelsim_proc_tmpl, encoding='utf-8').read()) # 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) else: logger.info("Created runsim and proc files") logger.info(f"runsim_filename {runsim_filename}") logger.info(f"proc_filename {proc_filename}") def run_command(taskname, logfile, command, exit_if_fail=True): # os.chdir(os.pardir) logger.info("Launching %s " % taskname) with open(logfile, 'w+') as output: try: output.write(os.getcwd() + "\n") output.write(" ".join(command)+"\n") process = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) output.write(process.stdout) if process.returncode: logger.error("%s run failed with returncode %d" % (taskname, process.returncode)) except (Exception, subprocess.CalledProcessError) as e: logger.exception("failed to execute %s" % taskname) return None logger.info("%s is written in file %s" % (taskname, logfile)) return process.stdout if __name__ == "__main__": main()