mirror of
https://github.com/YosysHQ/sby.git
synced 2025-08-09 14:51:26 +00:00
Initial support for a multi-task property status database
This adds initial support for an sqlite database that is shared across multiple tasks of a single SBY file and that can track the status of individual properties. The amount of information tracked in the database is currently quite minimal and depends on the engine and options used. This can be incrementally extended in the future. The ways in which the information in the database can be queries is even more limited for this initial version, consisting of a single '--status' option which lists all properties and their status.
This commit is contained in:
parent
5c649c8e75
commit
52184e5bf0
8 changed files with 462 additions and 5 deletions
|
@ -27,6 +27,7 @@ from shutil import copyfile, copytree, rmtree
|
|||
from select import select
|
||||
from time import monotonic, localtime, sleep, strftime
|
||||
from sby_design import SbyProperty, SbyModule, design_hierarchy
|
||||
from sby_status import SbyStatusDb
|
||||
|
||||
all_procs_running = []
|
||||
|
||||
|
@ -674,20 +675,41 @@ class SbySummary:
|
|||
self.engine_summaries[engine_idx] = SbyEngineSummary(engine_idx)
|
||||
return self.engine_summaries[engine_idx]
|
||||
|
||||
def add_event(self, *args, **kwargs):
|
||||
def add_event(self, *args, update_status=True, **kwargs):
|
||||
event = SbySummaryEvent(*args, **kwargs)
|
||||
|
||||
engine = self.engine_summary(event.engine_idx)
|
||||
|
||||
if update_status:
|
||||
status_metadata = dict(source="summary_event", engine=engine.engine)
|
||||
|
||||
if event.prop:
|
||||
if event.type == "$assert":
|
||||
event.prop.status = "FAIL"
|
||||
if event.path:
|
||||
event.prop.tracefiles.append(event.path)
|
||||
if update_status:
|
||||
self.task.status_db.add_task_property_data(
|
||||
event.prop,
|
||||
"trace",
|
||||
data=dict(path=event.path, step=event.step, **status_metadata),
|
||||
)
|
||||
if event.prop:
|
||||
if event.type == "$cover":
|
||||
event.prop.status = "PASS"
|
||||
if event.path:
|
||||
event.prop.tracefiles.append(event.path)
|
||||
|
||||
engine = self.engine_summary(event.engine_idx)
|
||||
if update_status:
|
||||
self.task.status_db.add_task_property_data(
|
||||
event.prop,
|
||||
"trace",
|
||||
data=dict(path=event.path, step=event.step, **status_metadata),
|
||||
)
|
||||
if event.prop and update_status:
|
||||
self.task.status_db.set_task_property_status(
|
||||
event.prop,
|
||||
data=status_metadata
|
||||
)
|
||||
|
||||
if event.trace not in engine.traces:
|
||||
engine.traces[event.trace] = SbyTraceSummary(event.trace, path=event.path, engine_case=event.engine_case)
|
||||
|
@ -1041,6 +1063,10 @@ class SbyTask(SbyConfig):
|
|||
if self.design == None:
|
||||
with open(f"{self.workdir}/model/design.json") as f:
|
||||
self.design = design_hierarchy(f)
|
||||
self.status_db.create_task_properties([
|
||||
prop for prop in self.design.properties_by_path.values()
|
||||
if not prop.type.assume_like
|
||||
])
|
||||
|
||||
def instance_hierarchy_error_callback(retcode):
|
||||
self.precise_prop_status = False
|
||||
|
@ -1186,8 +1212,13 @@ class SbyTask(SbyConfig):
|
|||
self.status = "ERROR"
|
||||
self.terminate()
|
||||
|
||||
def pass_unknown_asserts(self, data):
|
||||
for prop in self.design.pass_unknown_asserts():
|
||||
self.status_db.set_task_property_status(prop, data=data)
|
||||
|
||||
def update_status(self, new_status):
|
||||
assert new_status in ["PASS", "FAIL", "UNKNOWN", "ERROR"]
|
||||
self.status_db.set_task_status(new_status)
|
||||
|
||||
if new_status == "UNKNOWN":
|
||||
return
|
||||
|
@ -1199,7 +1230,7 @@ class SbyTask(SbyConfig):
|
|||
assert self.status != "FAIL"
|
||||
self.status = "PASS"
|
||||
if self.opt_mode in ("bmc", "prove") and self.design:
|
||||
self.design.pass_unknown_asserts()
|
||||
self.pass_unknown_asserts(dict(source="task_status"))
|
||||
|
||||
elif new_status == "FAIL":
|
||||
assert self.status != "PASS"
|
||||
|
@ -1258,6 +1289,19 @@ class SbyTask(SbyConfig):
|
|||
|
||||
self.handle_bool_option("assume_early", True)
|
||||
|
||||
def setup_status_db(self, status_path=None):
|
||||
if hasattr(self, 'status_db'):
|
||||
return
|
||||
|
||||
if status_path is None:
|
||||
try:
|
||||
with open(f"{self.workdir}/status.path", "r") as status_path_file:
|
||||
status_path = f"{self.workdir}/{status_path_file.read().rstrip()}"
|
||||
except FileNotFoundError:
|
||||
status_path = f"{self.workdir}/status.sqlite"
|
||||
|
||||
self.status_db = SbyStatusDb(status_path, self)
|
||||
|
||||
def setup_procs(self, setupmode):
|
||||
self.handle_non_engine_options()
|
||||
if self.opt_smtc is not None:
|
||||
|
@ -1285,6 +1329,8 @@ class SbyTask(SbyConfig):
|
|||
self.retcode = 0
|
||||
return
|
||||
|
||||
self.setup_status_db()
|
||||
|
||||
if self.opt_make_model is not None:
|
||||
for name in self.opt_make_model.split(","):
|
||||
self.model(name.strip())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue