mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: integrate formal verification for bus and nmi2apb protocols
- Added formal verification support for bus and nmi2apb protocols using SymbiYosys and Bitwuzla. - Introduced new formal design and properties files for both protocols. - Updated the build system to include formal verification steps in the Makefile. - Enhanced the doctor script to check for formal tool availability. - Added scripts for generating formal file lists and SymbiYosys configurations. - Implemented a wrapper for Bitwuzla to adapt Yosys legacy arguments. - Updated documentation to reflect new formal verification capabilities. - Added tests to ensure correctness of formal file generation and result summarization.
This commit is contained in:
17 files changed
+893
-8
No files matched your search
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Adapt Yosys' legacy Bitwuzla invocation to the Bitwuzla 0.9 CLI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def translate_arguments(arguments: list[str]) -> list[str]:
|
||||
"""Replace obsolete Yosys solver flags with Bitwuzla 0.9 equivalents."""
|
||||
translated = [argument for argument in arguments if argument not in ("--smt2", "-i")]
|
||||
return ["--lang", "smt2", *translated]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
executable = os.environ.get("RETROSOC_BITWUZLA")
|
||||
if not executable:
|
||||
print("RETROSOC_BITWUZLA must name the Bitwuzla 0.9 executable", file=sys.stderr)
|
||||
return 2
|
||||
wrapper = Path(__file__).resolve()
|
||||
if Path(executable).resolve() == wrapper:
|
||||
print(
|
||||
"RETROSOC_BITWUZLA must name the Bitwuzla executable, not its compatibility wrapper",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 2
|
||||
os.execvp(executable, [executable, *translate_arguments(sys.argv[1:])])
|
||||
return 127
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
+9
-4
@@ -25,6 +25,7 @@ def parse_args() -> argparse.Namespace:
|
||||
parser.add_argument("--pdk", required=True)
|
||||
parser.add_argument("--core", required=True)
|
||||
parser.add_argument("--ip", required=True)
|
||||
parser.add_argument("--formal", choices=("YES", "NO"), default="NO")
|
||||
parser.add_argument("--lock", type=Path, default=DEFAULT_LOCK)
|
||||
parser.add_argument("--format", choices=("text", "json"), default="text")
|
||||
parser.add_argument("--output", type=Path)
|
||||
@@ -65,6 +66,8 @@ def main() -> int:
|
||||
tools.append("yosys")
|
||||
if args.sta == "OPENSTA":
|
||||
tools.append("sta")
|
||||
if args.formal == "YES":
|
||||
tools.extend(("sby", "yosys", "yosys-smtbmc", "sv2v", "bitwuzla"))
|
||||
|
||||
source_names = ["mpw", "cluster_common", "third_party_ip"]
|
||||
pdk_names = {
|
||||
@@ -75,9 +78,7 @@ def main() -> int:
|
||||
}
|
||||
if args.pdk in pdk_names:
|
||||
source_names.append(pdk_names[args.pdk])
|
||||
paths = {
|
||||
name: root / lock["sources"][name]["destination"] for name in source_names
|
||||
}
|
||||
paths = {name: root / lock["sources"][name]["destination"] for name in source_names}
|
||||
tool_results = {
|
||||
tool: {"path": shutil.which(tool), "version": version(tool)}
|
||||
for tool in dict.fromkeys(tools)
|
||||
@@ -108,7 +109,11 @@ def main() -> int:
|
||||
for name, value in path_results.items():
|
||||
suffix = "[ok]" if value["exists"] else "[MISSING]"
|
||||
print(f" {name:<28} {value['path']} {suffix}")
|
||||
print("doctor: all selected requirements are available" if not failures else f"doctor found {failures} missing requirement(s)")
|
||||
print(
|
||||
"doctor: all selected requirements are available"
|
||||
if not failures
|
||||
else f"doctor found {failures} missing requirement(s)"
|
||||
)
|
||||
return int(failures != 0)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user