2019-09-07 11:36:22 -05:00
|
|
|
from string import Template
|
|
|
|
import sys
|
|
|
|
import os
|
2019-09-27 15:00:57 -05:00
|
|
|
import pprint
|
2019-09-07 11:36:22 -05:00
|
|
|
import argparse
|
|
|
|
import subprocess
|
|
|
|
import logging
|
|
|
|
from pprint import pprint
|
2019-09-27 15:00:57 -05:00
|
|
|
from configparser import ConfigParser
|
2019-09-07 11:36:22 -05:00
|
|
|
|
|
|
|
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
|
|
|
# Configure logging system
|
|
|
|
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
2022-11-21 16:21:31 -06:00
|
|
|
logging.basicConfig(
|
|
|
|
level=logging.INFO, stream=sys.stdout, format="%(levelname)s (%(threadName)10s) - %(message)s"
|
|
|
|
)
|
|
|
|
logger = logging.getLogger("Modelsim_run_log")
|
2019-09-07 11:36:22 -05:00
|
|
|
|
2019-09-27 15:00:57 -05:00
|
|
|
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
|
|
|
# Parse commandline arguments
|
|
|
|
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
2019-09-07 11:36:22 -05:00
|
|
|
parser = argparse.ArgumentParser()
|
2022-11-21 16:21:31 -06:00
|
|
|
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")
|
2019-09-07 11:36:22 -05:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
2019-09-27 15:00:57 -05:00
|
|
|
# Consider default formality script template
|
|
|
|
if not args.formality_template:
|
2019-09-07 11:36:22 -05:00
|
|
|
task_script_dir = os.path.dirname(os.path.abspath(__file__))
|
2022-11-21 16:21:31 -06:00
|
|
|
args.formality_template = os.path.join(
|
|
|
|
task_script_dir, os.pardir, "misc", "formality_template.tcl"
|
|
|
|
)
|
2019-09-07 11:36:22 -05:00
|
|
|
|
2019-09-27 15:00:57 -05:00
|
|
|
args.formality_template = os.path.abspath(args.formality_template)
|
2019-09-07 11:36:22 -05:00
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
for eachFile in args.files:
|
|
|
|
eachFile = os.path.abspath(eachFile)
|
2019-09-27 15:00:57 -05:00
|
|
|
pDir = os.path.dirname(eachFile)
|
|
|
|
os.chdir(pDir)
|
|
|
|
|
|
|
|
config = ConfigParser()
|
|
|
|
config.read(eachFile)
|
|
|
|
|
2022-11-21 16:21:31 -06:00
|
|
|
port_map = "set_user_match r:%s/%%s i:/WORK/%%s -type port -noninverted" % (
|
2019-09-27 15:00:57 -05:00
|
|
|
"/WORK/" + config["BENCHMARK_INFO"]["src_top_module"]
|
2022-11-21 16:21:31 -06:00
|
|
|
)
|
|
|
|
cell_map = "set_user_match r:%s/%%s i:/WORK/%%s -type cell -noninverted" % (
|
2019-09-27 15:00:57 -05:00
|
|
|
"/WORK/" + config["BENCHMARK_INFO"]["src_top_module"]
|
2022-11-21 16:21:31 -06:00
|
|
|
)
|
2019-09-27 15:00:57 -05:00
|
|
|
|
|
|
|
lables = {
|
|
|
|
"SOURCE_DESIGN_FILES": config["BENCHMARK_INFO"]["benchmark_netlist"],
|
|
|
|
"SOURCE_TOP_MODULE": "/WORK/" + config["BENCHMARK_INFO"]["src_top_module"],
|
|
|
|
"IMPL_DESIGN_FILES": " ".join(
|
2022-11-21 16:21:31 -06:00
|
|
|
[val for key, val in config["FPGA_INFO"].items() if "impl_netlist_" in key]
|
|
|
|
),
|
2019-09-27 15:00:57 -05:00
|
|
|
"IMPL_TOP_DIR": "/WORK/" + config["FPGA_INFO"]["impl_top_module"],
|
2022-11-21 16:21:31 -06:00
|
|
|
"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()]
|
|
|
|
),
|
2019-09-27 15:00:57 -05:00
|
|
|
}
|
|
|
|
|
2022-11-21 16:21:31 -06:00
|
|
|
tmpl = Template(open(args.formality_template, encoding="utf-8").read())
|
|
|
|
with open(os.path.join(pDir, "Output.tcl"), "w", encoding="utf-8") as tclout:
|
2019-09-07 11:36:22 -05:00
|
|
|
tclout.write(tmpl.substitute(lables))
|
|
|
|
if args.run_sim:
|
|
|
|
formality_run_string = ["formality", "-file", "Output.tcl"]
|
2019-09-27 15:00:57 -05:00
|
|
|
run_command("Formality Run", "formality_run.log", formality_run_string)
|
2019-09-07 11:36:22 -05:00
|
|
|
else:
|
2022-11-21 16:21:31 -06:00
|
|
|
with open("Output.tcl", "r", encoding="utf-8") as tclout:
|
2019-09-07 11:36:22 -05:00
|
|
|
print(tclout.read())
|
|
|
|
|
|
|
|
|
|
|
|
def run_command(taskname, logfile, command, exit_if_fail=True):
|
2019-09-27 15:00:57 -05:00
|
|
|
os.chdir(os.pardir)
|
2019-09-07 11:36:22 -05:00
|
|
|
logger.info("Launching %s " % taskname)
|
2022-11-21 16:21:31 -06:00
|
|
|
with open(logfile, "w+") as output:
|
2019-09-07 11:36:22 -05:00
|
|
|
try:
|
2022-11-21 16:21:31 -06:00
|
|
|
output.write(" ".join(command) + "\n")
|
|
|
|
process = subprocess.run(
|
|
|
|
command,
|
|
|
|
check=True,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
universal_newlines=True,
|
|
|
|
)
|
2019-09-07 11:36:22 -05:00
|
|
|
output.write(process.stdout)
|
|
|
|
if process.returncode:
|
2022-11-21 16:21:31 -06:00
|
|
|
logger.error("%s run failed with returncode %d" % (taskname, process.returncode))
|
2019-09-07 11:36:22 -05:00
|
|
|
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()
|