OpenFPGA/openfpga_flow/scripts/run_modelsim.py

149 lines
6.3 KiB
Python

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()