mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
- Adjusted slot assignments in to reflect new peripheral mappings. - Updated to validate new OpenC906 configurations, including generator and profile checks. - Modified to reference the new Std-series VexiiRiscv generator. - Changed cache maintenance instructions in to align with C906 specifications. - Revised assertions in to account for internal unit removals. - Updated to reflect changes in peripheral interface counts and policies. - Added new test file to ensure preservation of the frozen HP configuration in the Std-series generator.
133 lines
4.5 KiB
Python
133 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate the locked VexiiRiscv Std-series core below the selected build variant.
|
|
|
|
The generator is a Std-series asset preserved from the retired Mini HP
|
|
configuration; Mini no longer consumes it.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
GENERATOR_CLASS = "vexiiriscv.GenerateRetroSocStd"
|
|
GENERATED_MODULE = "vexiiriscv_std_generated"
|
|
|
|
|
|
def run(command: list[str], cwd: Path) -> str:
|
|
result = subprocess.run(command, cwd=cwd, check=True, capture_output=True, text=True)
|
|
return result.stdout.strip()
|
|
|
|
|
|
def git_revision(source: Path) -> str:
|
|
return run(["git", "rev-parse", "HEAD"], source)
|
|
|
|
|
|
def git_status(source: Path) -> list[str]:
|
|
output = run(["git", "status", "--short"], source)
|
|
return output.splitlines() if output else []
|
|
|
|
|
|
def sha256(path: Path) -> str:
|
|
digest = hashlib.sha256()
|
|
with path.open("rb") as source:
|
|
for chunk in iter(lambda: source.read(1024 * 1024), b""):
|
|
digest.update(chunk)
|
|
return digest.hexdigest()
|
|
|
|
|
|
def locked_revision(lock_path: Path) -> str:
|
|
document: dict[str, Any] = json.loads(lock_path.read_text(encoding="utf-8"))
|
|
source = document.get("sources", {}).get("vexiiriscv")
|
|
if not isinstance(source, dict) or not isinstance(source.get("revision"), str):
|
|
raise ValueError("dependency lock has no vexiiriscv source revision")
|
|
return source["revision"]
|
|
|
|
|
|
def validate_locked_source(source: Path, expected: str) -> str:
|
|
actual = git_revision(source)
|
|
if actual != expected:
|
|
raise ValueError(f"VexiiRiscv revision mismatch: expected {expected}, found {actual}")
|
|
status = git_status(source)
|
|
if status:
|
|
raise ValueError("VexiiRiscv source has local changes:\n" + "\n".join(status))
|
|
return actual
|
|
|
|
|
|
def generate(args: argparse.Namespace) -> None:
|
|
root = args.root.resolve()
|
|
source = args.source.resolve()
|
|
output = args.output.resolve()
|
|
expected = locked_revision(args.lock.resolve())
|
|
actual = validate_locked_source(source, expected)
|
|
|
|
scala_dir = root / "scripts" / "vexiiriscv"
|
|
output.mkdir(parents=True, exist_ok=True)
|
|
command = [
|
|
str(args.sbt),
|
|
"--batch",
|
|
f'set Compile / unmanagedSourceDirectories += file("{scala_dir}")',
|
|
f"runMain {GENERATOR_CLASS} {output}",
|
|
]
|
|
environment = os.environ.copy()
|
|
sbt_cache = root / ".cache/retrosoc/sbt"
|
|
sbt_cache.mkdir(parents=True, exist_ok=True)
|
|
inherited = environment.get("JAVA_TOOL_OPTIONS", "").strip()
|
|
java_options = (
|
|
f"-Duser.home={sbt_cache} "
|
|
f"-Dsbt.global.base={sbt_cache / 'global'} "
|
|
f"-Dsbt.boot.directory={sbt_cache / 'boot'} "
|
|
f"-Dsbt.ivy.home={sbt_cache / 'ivy'}"
|
|
" -Dsbt.server.autostart=false"
|
|
)
|
|
environment["JAVA_TOOL_OPTIONS"] = f"{inherited} {java_options}".strip()
|
|
environment["COURSIER_CACHE"] = str(sbt_cache / "coursier")
|
|
subprocess.run(command, cwd=source, check=True, env=environment)
|
|
|
|
generated = output / "vexiiriscv_std_generated.v"
|
|
if not generated.is_file():
|
|
raise FileNotFoundError(f"VexiiRiscv generator did not create {generated}")
|
|
validate_locked_source(source, expected)
|
|
|
|
submodules = run(["git", "submodule", "status", "--recursive"], source).splitlines()
|
|
manifest = {
|
|
"schema_version": 1,
|
|
"module": GENERATED_MODULE,
|
|
"product": "std",
|
|
"configuration": "rv64imafdc_zicbom_max",
|
|
"xlen": 64,
|
|
"physical_address_width": 32,
|
|
"mmu": "sv39",
|
|
"vexiiriscv_revision": actual,
|
|
"source_status": [],
|
|
"submodules": submodules,
|
|
"generator": str((scala_dir / "GenerateRetroSocStd.scala").relative_to(root)),
|
|
"files": {generated.name: sha256(generated)},
|
|
}
|
|
args.manifest.resolve().parent.mkdir(parents=True, exist_ok=True)
|
|
args.manifest.resolve().write_text(
|
|
json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8"
|
|
)
|
|
(output / "vexiiriscv.fl").write_text(str(generated) + "\n", encoding="utf-8")
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--root", type=Path, required=True)
|
|
parser.add_argument("--source", type=Path, required=True)
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
parser.add_argument("--manifest", type=Path, required=True)
|
|
parser.add_argument("--lock", type=Path, required=True)
|
|
parser.add_argument("--sbt", type=Path, required=True)
|
|
generate(parser.parse_args())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|