Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/flow-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ jobs:
tests/test_parameter_profiles.sh
tests/test_coverage_qualification.sh
tests/test_qualification_campaigns.sh
tests/test_static_intent.sh

- name: Run containerized release-manifest fixture
run: FIXTURE_CONTEXT=container tests/test_release_manifest.sh
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ methodology without copying flow scripts or changing module RTL.
- Named parameter-profile qualification across elaboration and implementation
- Declarative HDL and formal coverage qualification with reviewed exclusions
- Declarative negative-test and four-state qualification with explicit controls
- Declarative, license-independent SDC and UPF intent validation
- Flow selection, statuses, reports, and quality gates
- Schema-validated release evidence with input hashes and tool identities
- Pinned open-source tool installers and versions
Expand All @@ -38,6 +39,7 @@ reference, and links to:
- PyUVM, SVA, and coverage reuse across verification environments
- Every open-source and commercial flow
- Results, quality gates, waivers, and release evidence
- Portable SDC and UPF intent checks and their signoff boundary
- Methodology development, qualification, and release procedures

## Consumer quick start
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.6.0
0.7.0
3 changes: 3 additions & 0 deletions ci/check_flow_quality.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ python3 -m py_compile ci/parameter_profiles.py
python3 -m py_compile ci/release_manifest.py
python3 -m py_compile ci/coverage_qualification.py
python3 -m py_compile ci/qualification_campaign.py
python3 -m py_compile ci/static_intent.py
python3 -m json.tool schemas/release-evidence-v1.schema.json >/dev/null
python3 -m json.tool schemas/coverage-policy-v1.schema.json >/dev/null
python3 -m json.tool schemas/qualification-campaigns-v1.schema.json >/dev/null
python3 -m json.tool schemas/static-intent-v1.schema.json >/dev/null

if ! grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' VERSION; then
echo "VERSION must contain a semantic version such as 1.2.3" >&2
Expand Down Expand Up @@ -82,4 +84,5 @@ tests/test_parameter_profiles.sh
tests/test_release_manifest.sh
tests/test_coverage_qualification.sh
tests/test_qualification_campaigns.sh
tests/test_static_intent.sh
echo "mosaic-flow static quality checks passed"
2 changes: 1 addition & 1 deletion ci/open_source_quality_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ flow_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=flow_selection.sh
source "${flow_root}/ci/flow_selection.sh"

required_flows=(verible_lint verible_format slang_elaboration verilator_lint yosys_synthesis symbiyosys_formal eqy_equivalence verilator_sim pyuvm_open_source coverage_qualification negative_qualification four_state_qualification)
required_flows=(verible_lint verible_format slang_elaboration verilator_lint yosys_synthesis symbiyosys_formal eqy_equivalence verilator_sim pyuvm_open_source coverage_qualification negative_qualification four_state_qualification static_intent)
failed=0

for flow_name in "${required_flows[@]}"; do
Expand Down
1 change: 1 addition & 0 deletions ci/parameter_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"pyuvm_open_source",
"negative_qualification",
"four_state_qualification",
"static_intent",
"vcs_sim",
"pyuvm_commercial",
"synopsys_synthesis",
Expand Down
46 changes: 46 additions & 0 deletions ci/release_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,46 @@ def collect_qualification_inputs(
collector.add(declared_input, "declared")


def collect_static_intent_inputs(
collector: InputCollector, module_root: Path, required_flows: set[str]
) -> None:
"""Hash the expectation file and every SDC or UPF path it selects."""
if "static_intent" not in required_flows:
return
config_path = Path(
os.environ.get(
"STATIC_INTENT_CONFIG",
str(module_root / "config" / "static-intent.json"),
)
)
if not config_path.is_absolute():
config_path = module_root / config_path
collector.add(config_path, "declared")
try:
config = json.loads(config_path.read_text(encoding="utf-8"))
except (OSError, UnicodeError, json.JSONDecodeError) as error:
raise ReleaseError(
f"Cannot parse static-intent inputs from {config_path}: {error}"
) from error
if not isinstance(config, dict):
raise ReleaseError("Static-intent configuration root must be an object")
sdc = config.get("sdc", {})
if not isinstance(sdc, dict):
raise ReleaseError("Static-intent sdc section must be an object")
profiles = sdc.get("profiles", [])
if not isinstance(profiles, list):
raise ReleaseError("Static-intent SDC profiles must be an array")
for index, profile in enumerate(profiles):
if not isinstance(profile, dict) or not isinstance(profile.get("path"), str):
raise ReleaseError(f"Static-intent SDC profile {index} has no path")
collector.add(profile["path"], "declared")
upf = config.get("upf")
if upf is not None:
if not isinstance(upf, dict) or not isinstance(upf.get("path"), str):
raise ReleaseError("Static-intent UPF section has no path")
collector.add(upf["path"], "declared")


def generate_manifest(module_root: Path, flow_root: Path, report_dir: Path) -> dict[str, object]:
"""Validate release evidence and compose deterministic and volatile sections."""
module_root = module_root.resolve()
Expand Down Expand Up @@ -645,6 +685,7 @@ def generate_manifest(module_root: Path, flow_root: Path, report_dir: Path) -> d

flows, required_flows = collect_flows(module_root, report_dir)
collect_qualification_inputs(collector, module_root, required_flows)
collect_static_intent_inputs(collector, module_root, required_flows)
gates = collect_supplemental_gates(module_root, report_dir)
additional_evidence = []
for declared_path in environment_list("RELEASE_ADDITIONAL_EVIDENCE"):
Expand All @@ -656,6 +697,11 @@ def generate_manifest(module_root: Path, flow_root: Path, report_dir: Path) -> d
summary_path = report_dir / flow / "summary.json"
if flow in required_flows and summary_path.is_file():
additional_evidence.append(evidence_entry(summary_path, module_root))
if "static_intent" in required_flows:
for filename in ("sdc-findings.json", "upf-findings.json", "summary.json"):
additional_evidence.append(
evidence_entry(report_dir / "static_intent" / filename, module_root)
)

parameters = json_environment("PROFILE_PARAMETERS_JSON", {})
technology_details = json_environment("RELEASE_TECHNOLOGY_METADATA_JSON", {})
Expand Down
Loading
Loading