mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
- Introduced SYNTH_RECIPE variable to select between balanced, area, and speed synthesis recipes. - Updated Makefile to handle new SYNTH_RECIPE variable and its validation. - Modified synthesis scripts to utilize the selected recipe, ensuring outputs are directed to the appropriate directories. - Enhanced documentation to reflect changes in synthesis flow and directory structure. - Added tests to verify correct behavior of new synthesis recipes and their integration into the regression suite. - Removed obsolete scripts and configurations related to previous synthesis methods.
64 lines
2.1 KiB
Python
Executable File
64 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Derive the Yosys ABC target period from the SoC clock/reset inventory."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
def require_object(value: Any, field: str) -> dict[str, Any]:
|
|
if not isinstance(value, dict):
|
|
raise ValueError(f"{field} must be an object")
|
|
return value
|
|
|
|
|
|
def require_string(value: Any, field: str) -> str:
|
|
if not isinstance(value, str) or not value:
|
|
raise ValueError(f"{field} must be a non-empty string")
|
|
return value
|
|
|
|
|
|
def period_ps(document: dict[str, Any], domain: str = "external") -> int:
|
|
require_string(domain, "domain")
|
|
domains = document.get("domains")
|
|
if not isinstance(domains, list) or not domains:
|
|
raise ValueError("domains must be a non-empty list")
|
|
for entry in domains:
|
|
item = require_object(entry, "domains entry")
|
|
if item.get("name") != domain:
|
|
continue
|
|
sta = require_object(item.get("sta"), f"domain {domain}.sta")
|
|
period_ns = sta.get("period_ns")
|
|
if not isinstance(period_ns, (int, float)) or isinstance(period_ns, bool) or period_ns <= 0:
|
|
raise ValueError(f"domain {domain}.sta.period_ns must be a positive number")
|
|
return round(float(period_ns) * 1000)
|
|
raise ValueError(f"domain {domain} is not declared")
|
|
|
|
|
|
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--domains", type=Path, required=True)
|
|
parser.add_argument("--domain", default="external")
|
|
return parser.parse_args(argv)
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
args = parse_args(argv)
|
|
try:
|
|
document = require_object(
|
|
json.loads(args.domains.read_text(encoding="utf-8")), "domain map"
|
|
)
|
|
print(period_ps(document, args.domain))
|
|
except (OSError, ValueError, json.JSONDecodeError) as error:
|
|
print(error, file=sys.stderr)
|
|
return 1
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|