mirror of
				https://github.com/YosysHQ/sby.git
				synced 2025-10-31 04:52:30 +00:00 
			
		
		
		
	Merge pull request #298 from YosysHQ/george/smtbmc_paths
smtbmc: match on full property paths instead of just names
This commit is contained in:
		
						commit
						117fb26c68
					
				
					 3 changed files with 42 additions and 34 deletions
				
			
		|  | @ -139,32 +139,26 @@ class SbyModule: | ||||||
|     def get_property_list(self): |     def get_property_list(self): | ||||||
|         return [p for p in self if p.type != p.Type.ASSUME] |         return [p for p in self if p.type != p.Type.ASSUME] | ||||||
| 
 | 
 | ||||||
|     def find_property(self, hierarchy, location): |     def find_property(self, path, cell_name, trans_dict=dict()): | ||||||
|         # FIXME: use that RE that works with escaped paths from https://stackoverflow.com/questions/46207665/regex-pattern-to-split-verilog-path-in-different-instances-using-python |  | ||||||
|         path = hierarchy.split('.') |  | ||||||
|         mod = path.pop(0) |  | ||||||
|         if self.name != mod: |  | ||||||
|             raise ValueError(f"{self.name} is not the first module in hierarchical path {hierarchy}.") |  | ||||||
|         try: |  | ||||||
|             mod_hier = self |  | ||||||
|             while path: |  | ||||||
|                 mod = path.pop(0) |  | ||||||
|                 mod_hier = mod_hier.submodules[mod] |  | ||||||
|         except KeyError: |  | ||||||
|             raise KeyError(f"Could not find {hierarchy} in design hierarchy!") |  | ||||||
|         try: |  | ||||||
|             prop = next(p for p in mod_hier.properties if location in p.location) |  | ||||||
|         except StopIteration: |  | ||||||
|             raise KeyError(f"Could not find assert at {location} in properties list!") |  | ||||||
|         return prop |  | ||||||
| 
 |  | ||||||
|     def find_property_by_cellname(self, cell_name, trans_dict=dict()): |  | ||||||
|         # backends may need to mangle names irreversibly, so allow applying |         # backends may need to mangle names irreversibly, so allow applying | ||||||
|         # the same transformation here |         # the same transformation here | ||||||
|         for prop in self: |         trans = str.maketrans(trans_dict) | ||||||
|             if cell_name == prop.name.translate(str.maketrans(trans_dict)): |         path_iter = iter(path) | ||||||
|  | 
 | ||||||
|  |         mod = next(path_iter).translate(trans) | ||||||
|  |         if self.name != mod: | ||||||
|  |             raise ValueError(f"{self.name} is not the first module in hierarchical path {pretty_path(path)}.") | ||||||
|  | 
 | ||||||
|  |         mod_hier = self | ||||||
|  |         for mod in path_iter: | ||||||
|  |             mod_hier = next((v for k, v in mod_hier.submodules.items() if mod == k.translate(trans)), None) | ||||||
|  |             if not mod_hier: | ||||||
|  |                 raise KeyError(f"Could not find {pretty_path(path)} in design hierarchy!") | ||||||
|  | 
 | ||||||
|  |         prop = next((p for p in mod_hier.properties if cell_name == p.name.translate(trans)), None) | ||||||
|  |         if not prop: | ||||||
|  |             raise KeyError(f"Could not find property {cell_name} at location {pretty_print(path)} in properties list!") | ||||||
|         return prop |         return prop | ||||||
|         raise KeyError(f"No such property: {cell_name}") |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @dataclass | @dataclass | ||||||
|  |  | ||||||
|  | @ -202,6 +202,11 @@ def aigsmt_trace_callback(task, engine_idx, proc_status, *, run_aigsmt, smtbmc_v | ||||||
| 
 | 
 | ||||||
|             smt2_trans = {'\\':'/', '|':'/'} |             smt2_trans = {'\\':'/', '|':'/'} | ||||||
| 
 | 
 | ||||||
|  |             def parse_mod_path(path_string): | ||||||
|  |                 # Match a path with . as delimiter, allowing escaped tokens in | ||||||
|  |                 # verilog `\name ` format | ||||||
|  |                 return [m[1] or m[0] for m in re.findall(r"(\\([^ ]*) |[^\.]+)(?:\.|$)", path_string)] | ||||||
|  | 
 | ||||||
|             match = re.match(r"^## [0-9: ]+ .* in step ([0-9]+)\.\.", line) |             match = re.match(r"^## [0-9: ]+ .* in step ([0-9]+)\.\.", line) | ||||||
|             if match: |             if match: | ||||||
|                 current_step = int(match[1]) |                 current_step = int(match[1]) | ||||||
|  | @ -213,10 +218,11 @@ def aigsmt_trace_callback(task, engine_idx, proc_status, *, run_aigsmt, smtbmc_v | ||||||
|             match = re.match(r"^## [0-9: ]+ Status: PASSED", line) |             match = re.match(r"^## [0-9: ]+ Status: PASSED", line) | ||||||
|             if match: proc2_status = "PASS" |             if match: proc2_status = "PASS" | ||||||
| 
 | 
 | ||||||
|             match = re.match(r"^## [0-9: ]+ Assert failed in (\S+): (\S+)(?: \((\S+)\))?", line) |             match = re.match(r"^## [0-9: ]+ Assert failed in ([^:]+): (\S+)(?: \((\S+)\))?", line) | ||||||
|             if match: |             if match: | ||||||
|  |                 path = parse_mod_path(match[1]) | ||||||
|                 cell_name = match[3] or match[2] |                 cell_name = match[3] or match[2] | ||||||
|                 prop = task.design.hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans) |                 prop = task.design.hierarchy.find_property(path, cell_name, trans_dict=smt2_trans) | ||||||
|                 prop.status = "FAIL" |                 prop.status = "FAIL" | ||||||
|                 task.status_db.set_task_property_status(prop, data=dict(source="aigsmt", engine=f"engine_{engine_idx}")) |                 task.status_db.set_task_property_status(prop, data=dict(source="aigsmt", engine=f"engine_{engine_idx}")) | ||||||
|                 last_prop.append(prop) |                 last_prop.append(prop) | ||||||
|  |  | ||||||
|  | @ -203,6 +203,11 @@ def run(mode, task, engine_idx, engine): | ||||||
| 
 | 
 | ||||||
|         smt2_trans = {'\\':'/', '|':'/'} |         smt2_trans = {'\\':'/', '|':'/'} | ||||||
| 
 | 
 | ||||||
|  |         def parse_mod_path(path_string): | ||||||
|  |             # Match a path with . as delimiter, allowing escaped tokens in | ||||||
|  |             # verilog `\name ` format | ||||||
|  |             return [m[1] or m[0] for m in re.findall(r"(\\([^ ]*) |[^\.]+)(?:\.|$)", path_string)] | ||||||
|  | 
 | ||||||
|         match = re.match(r"^## [0-9: ]+ .* in step ([0-9]+)\.\.", line) |         match = re.match(r"^## [0-9: ]+ .* in step ([0-9]+)\.\.", line) | ||||||
|         if match: |         if match: | ||||||
|             current_step = int(match[1]) |             current_step = int(match[1]) | ||||||
|  | @ -228,19 +233,21 @@ def run(mode, task, engine_idx, engine): | ||||||
|             proc_status = "ERROR" |             proc_status = "ERROR" | ||||||
|             return line |             return line | ||||||
| 
 | 
 | ||||||
|         match = re.match(r"^## [0-9: ]+ Assert failed in (\S+): (\S+)(?: \((\S+)\))?", line) |         match = re.match(r"^## [0-9: ]+ Assert failed in ([^:]+): (\S+)(?: \((\S+)\))?", line) | ||||||
|         if match: |         if match: | ||||||
|  |             path = parse_mod_path(match[1]) | ||||||
|             cell_name = match[3] or match[2] |             cell_name = match[3] or match[2] | ||||||
|             prop = task.design.hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans) |             prop = task.design.hierarchy.find_property(path, cell_name, trans_dict=smt2_trans) | ||||||
|             prop.status = "FAIL" |             prop.status = "FAIL" | ||||||
|             task.status_db.set_task_property_status(prop, data=dict(source="smtbmc", engine=f"engine_{engine_idx}")) |             task.status_db.set_task_property_status(prop, data=dict(source="smtbmc", engine=f"engine_{engine_idx}")) | ||||||
|             last_prop.append(prop) |             last_prop.append(prop) | ||||||
|             return line |             return line | ||||||
| 
 | 
 | ||||||
|         match = re.match(r"^## [0-9: ]+ Reached cover statement at (\S+)(?: \((\S+)\))? in step \d+\.", line) |         match = re.match(r"^## [0-9: ]+ Reached cover statement in step \d+ at ([^:]+): (\S+)(?: \((\S+)\))?", line) | ||||||
|         if match: |         if match: | ||||||
|             cell_name = match[2] or match[1] |             path = parse_mod_path(match[1]) | ||||||
|             prop = task.design.hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans) |             cell_name = match[3] or match[2] | ||||||
|  |             prop = task.design.hierarchy.find_property(path, cell_name, trans_dict=smt2_trans) | ||||||
|             prop.status = "PASS" |             prop.status = "PASS" | ||||||
|             task.status_db.set_task_property_status(prop, data=dict(source="smtbmc", engine=f"engine_{engine_idx}")) |             task.status_db.set_task_property_status(prop, data=dict(source="smtbmc", engine=f"engine_{engine_idx}")) | ||||||
|             last_prop.append(prop) |             last_prop.append(prop) | ||||||
|  | @ -268,10 +275,11 @@ def run(mode, task, engine_idx, engine): | ||||||
|                 tracefile = match[1] |                 tracefile = match[1] | ||||||
|                 pending_sim = tracefile |                 pending_sim = tracefile | ||||||
| 
 | 
 | ||||||
|         match = re.match(r"^## [0-9: ]+ Unreached cover statement at (\S+) \((\S+)\)\.", line) |         match = re.match(r"^## [0-9: ]+ Unreached cover statement at ([^:]+): (\S+)(?: \((\S+)\))?", line) | ||||||
|         if match: |         if match: | ||||||
|             cell_name = match[2] |             path = parse_mod_path(match[1]) | ||||||
|             prop = task.design.hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans) |             cell_name = match[3] or match[2] | ||||||
|  |             prop = task.design.hierarchy.find_property(path, cell_name, trans_dict=smt2_trans) | ||||||
|             prop.status = "FAIL" |             prop.status = "FAIL" | ||||||
|             task.status_db.set_task_property_status(prop, data=dict(source="smtbmc", engine=f"engine_{engine_idx}")) |             task.status_db.set_task_property_status(prop, data=dict(source="smtbmc", engine=f"engine_{engine_idx}")) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue