blob: 6427d832665a1bb0e4d927dff61fa2dcb5639180 [file] [log] [blame]
import argparse
import logging
import subprocess
from pathlib import Path
def klayout_gds_drc_check(check_name, drc_script_path, gds_input_file_path, output_directory, klayout_cmd_extra_args=[]):
report_file_path = output_directory / 'outputs/reports' / f'{check_name}_check.xml'
logs_directory = output_directory / 'logs'
run_drc_check_cmd = ['klayout', '-b', '-r', drc_script_path,
'-rd', f"input={gds_input_file_path}",
'-rd', f"report={report_file_path}"]
# '-rd', "feol=true"]
run_drc_check_cmd.extend(klayout_cmd_extra_args)
log_file_path = logs_directory / f'{check_name}_check.log'
with open(log_file_path, 'w') as klayout_drc_log:
subprocess.run(run_drc_check_cmd, stderr=klayout_drc_log, stdout=klayout_drc_log)
with open(report_file_path) as klayout_xml_report:
drc_content = klayout_xml_report.read()
drc_count = drc_content.count('<item>')
total_file_path = logs_directory / f'{check_name}_check.total'
with open(total_file_path, 'w') as drc_total:
drc_total.write(f"{drc_count}")
if drc_count == 0:
logging.info("No DRC Violations found")
return True
else:
logging.error(f"Total # of DRC violations is {drc_count} Please check {report_file_path} For more details")
return False
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG, format=f"%(asctime)s | %(levelname)-7s | %(message)s", datefmt='%d-%b-%Y %H:%M:%S')
parser = argparse.ArgumentParser(description='Runs magic and klayout drc checks on a given GDS.')
parser.add_argument('--gds_input_file_path', '-g', required=True, help='GDS File to apply DRC checks on')
parser.add_argument('--output_directory', '-o', required=True, help='Output Directory')
parser.add_argument('--pdk_root', '-p', required=True, help='PDK Path')
parser.add_argument('--design_name', '-d', required=True, help='Design Name')
args = parser.parse_args()
gds_input_file_path = Path(args.gds_input_file_path)
output_directory = Path(args.output_directory)
pdk_root = Path(args.pdk_root)
design_name = args.design_name
klayout_sky130A_mr_drc_script_path = Path(__file__).parent.parent.parent / "tech-files/sky130A_mr.drc"
if gds_input_file_path.exists() and gds_input_file_path.suffix == ".gds":
if output_directory.exists() and output_directory.is_dir():
if klayout_gds_drc_check("klayout_feol_drc", gds_input_file_path, klayout_sky130A_mr_drc_script_path, output_directory, ["-rd", "feol=true"]):
logging.info("Klayout GDS DRC Clean")
else:
logging.info("Klayout GDS DRC Dirty")
else:
logging.error(f"{output_directory} is not valid")
else:
logging.error(f"{gds_input_file_path} is not valid")