/ extract_rules.py
extract_rules.py
1 #!/usr/bin/env python3 2 """Script to extract the rules from PDK files""" 3 # SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-or-later OR CERN-OHL-S-2.0+ OR Apache-2.0 4 # Currently this is manual extraction for a signal TSMC 0.18um 5 # Plan is to update this is the future to make it generic and driven 6 # by an input file. 7 8 import yaml 9 10 from pdkmaster import AssuraContext 11 12 print("TSMC_CM018RF") 13 14 with open("tf_yaml/TSMC_CM018RF_TechFile.yaml") as f: 15 tf = yaml.load(f, Loader=yaml.FullLoader) 16 with open("assura_yaml/TSMC_CM018RF_DRC.yaml") as f: 17 drc = yaml.load(f, Loader=yaml.FullLoader) 18 with open("assura_yaml/TSMC_CM018RF_Antenna.yaml") as f: 19 antenna = yaml.load(f, Loader=yaml.FullLoader) 20 # TODO: LVS and PEX 21 22 for expr in tf["TechFile"]: 23 for key, value in expr.items(): 24 if key == "constraintGroups": 25 tf_foundry = value["foundry"] 26 27 print("Techfile foundry constraints specified:") 28 for key in tf_foundry.keys(): 29 if key != "override": 30 print("\t{}".format(key)) 31 32 33 def _cond2str(expr): 34 if isinstance(expr, list): 35 return "("+" ".join(_cond2str(item) for item in expr)+")" 36 elif isinstance(expr, dict): 37 assert len(expr) == 1 38 for key, args in expr.items(): 39 return key+_cond2str(args) 40 else: 41 return str(expr) 42 43 class AssuraDRC(dict): 44 def extract_checks(self, value, *, condstr=""): 45 for expr in value: 46 if isinstance(expr, dict): 47 for key, value in expr.items(): 48 if key == "if": 49 condstr2 = _cond2str(value["cond"]) 50 if len(condstr) > 0: 51 condstr2 = condstr+"&&"+condstr2 52 self.extract_checks( 53 value=value["then"]["statements"], 54 condstr=condstr2, 55 ) 56 if "else" in value: 57 condstr2 = "!"+_cond2str(value["cond"]) 58 if len(condstr) > 0: 59 condstr2 = condstr+"&&"+condstr2 60 self.extract_checks( 61 value=value["else"]["statements"], 62 condstr=condstr2, 63 ) 64 elif key in ("drc", "errorLayer", "offGrid"): 65 self.add_check(condstr, key, value) 66 67 def add_check(self, condstr, checktype, check): 68 try: 69 conddata = self[condstr] 70 except KeyError: 71 self[condstr] = conddata = {} 72 73 try: 74 conddata[checktype].append(check) 75 except KeyError: 76 conddata[checktype] = [check] 77 78 def print_checks(self): 79 keys = list(self.keys()) 80 keys.sort() 81 82 for key in keys: 83 print("{}:".format("Unconditioned" if key == "" else key)) 84 for checktype, checks in self[key].items(): 85 print(" {}:".format(checktype)) 86 for check in checks: 87 print(" {}".format(check)) 88 89 def get_sigs(self): 90 sigs = {} 91 for _, checktypes in self.items(): 92 for checktype, checks in checktypes.items(): 93 if checktype not in ("drc", "errorLayer", "offGrid"): 94 continue 95 checksigs = set(tuple(type(expr) for expr in check) for check in checks) 96 if checktype in sigs: 97 sigs[checktype].update(checksigs) 98 else: 99 sigs[checktype] = checksigs 100 101 return sigs 102 103 # assura_drc = AssuraDRC() 104 # for expr in drc["SkillFile"]: 105 # if isinstance(expr, dict): 106 # for key, value in expr.items(): 107 # if key == "drcExtractRules": 108 # assura_drc.extract_checks(value["statements"]) 109 110 # #assura_drc.print_checks() 111 # print("drc signatures:") 112 # for checktype, sigs in assura_drc.get_sigs().items(): 113 # print(" {}:".format(checktype)) 114 # for sig in sigs: 115 # print(" {}".format(sig)) 116 117 context = AssuraContext() 118 ret = context.interpret(expr=drc["AssuraFile"], isstatements=True) 119 120 print("Assura DRC executed:") 121 print(" Returned: {}".format(ret)) 122 print(" Procedures:") 123 for name in context.procedures: 124 print(" {}".format(name)) 125 print(" Variables:") 126 for name, value in context.variables.items(): 127 print(" {}: {}".format(name, value)) 128 print(" Called: {}".format(context.called))