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="+") parser.add_argument("--formality_template", type=str, help="Modelsim verification template file") parser.add_argument("--run_sim", action="store_true", help="Execute generated script in formality") args = parser.parse_args() # Consider default formality script template if not args.formality_template: task_script_dir = os.path.dirname(os.path.abspath(__file__)) args.formality_template = os.path.join( task_script_dir, os.pardir, "misc", "formality_template.tcl" ) args.formality_template = os.path.abspath(args.formality_template) 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) port_map = "set_user_match r:%s/%%s i:/WORK/%%s -type port -noninverted" % ( "/WORK/" + config["BENCHMARK_INFO"]["src_top_module"] ) cell_map = "set_user_match r:%s/%%s i:/WORK/%%s -type cell -noninverted" % ( "/WORK/" + config["BENCHMARK_INFO"]["src_top_module"] ) lables = { "SOURCE_DESIGN_FILES": config["BENCHMARK_INFO"]["benchmark_netlist"], "SOURCE_TOP_MODULE": "/WORK/" + config["BENCHMARK_INFO"]["src_top_module"], "IMPL_DESIGN_FILES": " ".join( [val for key, val in config["FPGA_INFO"].items() if "impl_netlist_" in key] ), "IMPL_TOP_DIR": "/WORK/" + config["FPGA_INFO"]["impl_top_module"], "PORT_MAP_LIST": "\n".join([port_map % ele for ele in config["PORT_MATCHING"].items()]), "REGISTER_MAP_LIST": "\n".join( [cell_map % ele for ele in config["REGISTER_MATCH"].items()] ), } tmpl = Template(open(args.formality_template, encoding="utf-8").read()) with open(os.path.join(pDir, "Output.tcl"), "w", encoding="utf-8") as tclout: tclout.write(tmpl.substitute(lables)) if args.run_sim: formality_run_string = ["formality", "-file", "Output.tcl"] run_command("Formality Run", "formality_run.log", formality_run_string) else: with open("Output.tcl", "r", encoding="utf-8") as tclout: print(tclout.read()) 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(" ".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()