feat: add HP mailbox and PLIC tests; enhance existing test coverage

- Updated axi4_interconnect_tb to include an additional master and issue high-priority access tests.
- Introduced hp_mailbox_tb for testing the HP mailbox functionality, including register and doorbell operations.
- Added plic_tb to validate PLIC priority, claim, and completion mechanisms.
- Enhanced pll_ctrl_tb to initialize additional system control signals.
- Updated soc_irq_topology_tb to account for new IRQ sources and validate IRQ signal behavior.
- Improved sysctrl_tb to include tests for HP lifecycle control and status registers.
- Added tests for HP boot bundle layout, CRC, and payload validation.
- Introduced test_hp_mailbox.py for RTL regression testing of the HP mailbox.
- Added test_hp_platform.py to validate HP platform configuration and generated-source boundaries.
- Enhanced test_librelane_flow.py to ensure correct signal placement in chip configuration.
- Added performance log tests to validate LP and HP coremark ratios.
- Updated test_soc_topology.py to reflect changes in IRQ and peripheral mappings.
This commit is contained in:
maksyuki committed 2026-08-27 19:26:32 +08:00
1 parent f953ef7137
commit 8ba8a0ad47
101 files changed
+4880 -111

No files matched your search

+9
View File
@@ -25,6 +25,15 @@ SRAM CoreMark quick report into `meta/coremark.json`; it requires one valid
`COREMARK_RESULT` record and `COREMARK_PASS`. Both reports complement, rather
than replace, the common `SIM_TEST_PASS` simulation verdict.
`generate_vexiiriscv.py` verifies the locked VexiiRiscv revision and generates
the fixed HP core below `build/`; generated RTL is never tracked.
`setup_hp_linux.py` installs the locked OpenSBI, Linux, and Buildroot revisions
and can resume a checkout left without `HEAD` by an interrupted fetch.
`build_hp_linux.py` builds the RV32 `ilp32d` image set with the repo-owned
external OpenSBI platform. `package_hp_boot.py` creates the v1 LP/HP flash
bundle and its SHA-256/CRC manifest. `check_lp_hp_performance.py` applies the
measured 2.5x CoreMark/MHz gate.
`run_debug_session.py` is the local Hazard3 debug acceptance driver. It starts
the Verilator remote-bitbang endpoint, the lock-pinned OpenOCD binary, and
RISC-V GDB, then records their logs and a structured result. Invoke it through
+206
View File
@@ -0,0 +1,206 @@
#!/usr/bin/env python3
"""Build the pinned RV32 HP Buildroot, Linux, DTB, and OpenSBI images."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import shutil
import subprocess
from pathlib import Path
LAYOUT = {
"fw_jump.bin": (0x38000000, 512 * 1024),
"retrosoc_hp.dtb": (0x38080000, 64 * 1024),
"Image": (0x38400000, 12 * 1024 * 1024),
"rootfs.cpio.gz": (0x39000000, 8 * 1024 * 1024),
}
def command(arguments: list[str], cwd: Path) -> None:
environment = dict(os.environ)
environment.pop("CONFIG", None)
environment.pop("MAKEFLAGS", None)
environment.pop("MAKEOVERRIDES", None)
environment.pop("MFLAGS", None)
subprocess.run(arguments, cwd=cwd, check=True, env=environment)
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 require_source(path: Path, name: str) -> Path:
resolved = path.resolve()
if not (resolved / ".git").exists():
raise FileNotFoundError(f"missing locked {name} source: {resolved}; run setup-hp-linux")
return resolved
def source_revision(path: Path) -> str:
return subprocess.check_output(
["git", "-C", str(path), "rev-parse", "HEAD"], text=True
).strip()
def find_toolchain(buildroot_output: Path) -> str:
matches = sorted((buildroot_output / "host/bin").glob("riscv32*-linux-*-gcc"))
if len(matches) != 1:
raise RuntimeError(f"expected one RV32 Linux GCC in {buildroot_output / 'host/bin'}")
return str(matches[0])[: -len("gcc")]
def build(args: argparse.Namespace) -> None:
root = args.root.resolve()
output = args.output.resolve()
output.mkdir(parents=True, exist_ok=True)
buildroot = require_source(args.buildroot, "Buildroot")
linux = require_source(args.linux, "Linux")
opensbi = require_source(args.opensbi, "OpenSBI")
external = root / "app/ports/linux"
buildroot_output = output / "buildroot"
command(
["make", f"O={buildroot_output}", f"BR2_EXTERNAL={external}", "retrosoc_hp_defconfig"],
buildroot,
)
command(["make", f"O={buildroot_output}", f"BR2_EXTERNAL={external}", f"-j{args.jobs}"], buildroot)
cross_compile = find_toolchain(buildroot_output)
linux_output = output / "linux"
command(
["make", f"O={linux_output}", "ARCH=riscv", f"CROSS_COMPILE={cross_compile}", "tinyconfig"],
linux,
)
command(
[
str(linux / "scripts/kconfig/merge_config.sh"),
"-m",
"-O",
str(linux_output),
str(linux_output / ".config"),
str(external / "linux/retrosoc_hp.config"),
],
linux,
)
command(
["make", f"O={linux_output}", "ARCH=riscv", f"CROSS_COMPILE={cross_compile}", "olddefconfig"],
linux,
)
command(
["make", f"O={linux_output}", "ARCH=riscv", f"CROSS_COMPILE={cross_compile}",
f"-j{args.jobs}", "Image"],
linux,
)
image_dir = output / "images"
image_dir.mkdir(parents=True, exist_ok=True)
rootfs_source = buildroot_output / "images/rootfs.cpio.gz"
if not rootfs_source.is_file():
raise FileNotFoundError(f"HP Linux build output is missing: {rootfs_source}")
initrd_end = LAYOUT["rootfs.cpio.gz"][0] + rootfs_source.stat().st_size
command(
[
"dtc",
"-I",
"dts",
"-O",
"dtb",
"-o",
str(image_dir / "retrosoc_hp.dtb"),
str(external / "linux/retrosoc_hp.dts"),
],
root,
)
command(
[
"fdtput",
"-t",
"x",
str(image_dir / "retrosoc_hp.dtb"),
"/chosen",
"linux,initrd-end",
f"0x{initrd_end:08x}",
],
root,
)
opensbi_output = output / "opensbi"
command(
[
"make",
f"O={opensbi_output}",
f"CROSS_COMPILE={cross_compile}",
"PLATFORM=retrosoc_hp",
f"PLATFORM_DIR={external / 'opensbi'}",
"PLATFORM_RISCV_XLEN=32",
"PLATFORM_RISCV_ABI=ilp32d",
"PLATFORM_RISCV_ISA=rv32imafdc_zicsr_zifencei",
"FW_TEXT_START=0x38000000",
"FW_JUMP=y",
"FW_JUMP_ADDR=0x38400000",
"FW_JUMP_FDT_ADDR=0x38080000",
f"-j{args.jobs}",
],
opensbi,
)
copies = {
opensbi_output / "platform/retrosoc_hp/firmware/fw_jump.bin": image_dir / "fw_jump.bin",
linux_output / "arch/riscv/boot/Image": image_dir / "Image",
rootfs_source: image_dir / "rootfs.cpio.gz",
}
for source, destination in copies.items():
if not source.is_file():
raise FileNotFoundError(f"HP Linux build output is missing: {source}")
shutil.copy2(source, destination)
manifest: dict[str, object] = {
"schema_version": 1,
"boot_flow": "opensbi-fw_jump",
"hart_id": 1,
"sources": {
"buildroot": source_revision(buildroot),
"linux": source_revision(linux),
"opensbi": source_revision(opensbi),
},
"artifacts": {},
}
artifacts = manifest["artifacts"]
assert isinstance(artifacts, dict)
for name, (address, maximum) in LAYOUT.items():
path = image_dir / name
size = path.stat().st_size
if size > maximum:
raise ValueError(f"{name} is {size} bytes; maximum is {maximum}")
artifacts[name] = {
"address": f"0x{address:08X}",
"maximum_bytes": maximum,
"size_bytes": size,
"sha256": sha256(path),
}
(image_dir / "manifest.json").write_text(
json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--root", type=Path, required=True)
parser.add_argument("--buildroot", type=Path, required=True)
parser.add_argument("--linux", type=Path, required=True)
parser.add_argument("--opensbi", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--jobs", type=int, default=1)
build(parser.parse_args())
if __name__ == "__main__":
main()
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""Build the minimal hart-1 smoke payload used by HP RTL simulation."""
from __future__ import annotations
import argparse
import subprocess
from pathlib import Path
def build(args: argparse.Namespace) -> None:
output = args.output.resolve()
images = output / "images"
images.mkdir(parents=True, exist_ok=True)
elf = output / "hp_smoke.elf"
compiler = f"{args.cross}gcc"
objcopy = f"{args.cross}objcopy"
subprocess.run(
[
compiler,
"-march=rv32imafdc_zicsr_zifencei",
"-mabi=ilp32d",
"-nostdlib",
"-nostartfiles",
"-Wl,--build-id=none",
f"-Wl,-T,{args.linker.resolve()}",
"-o",
str(elf),
str(args.source.resolve()),
],
check=True,
)
subprocess.run(
[objcopy, "-O", "binary", str(elf), str(images / "fw_jump.bin")],
check=True,
)
(images / "retrosoc_hp.dtb").write_bytes(b"SMOK")
(images / "Image").write_bytes(b"SMOK")
(images / "rootfs.cpio.gz").write_bytes(b"SMOK")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--source", type=Path, required=True)
parser.add_argument("--linker", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--cross", default="riscv32-unknown-elf-")
build(parser.parse_args())
if __name__ == "__main__":
main()
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""Enforce the measured HP-to-LP CoreMark/MHz performance ratio."""
from __future__ import annotations
import argparse
import json
import sys
from decimal import Decimal, InvalidOperation
from pathlib import Path
def result(report: dict[str, object], label: str) -> dict[str, object]:
if report.get("status") != "passed":
raise ValueError(f"{label} CoreMark report did not pass")
results = report.get("results")
if not isinstance(results, list) or len(results) != 1 or not isinstance(results[0], dict):
raise ValueError(f"{label} CoreMark report must contain exactly one result")
return results[0]
def compare(
lp_report: dict[str, object], hp_report: dict[str, object], threshold: Decimal
) -> dict[str, object]:
if threshold <= 0:
raise ValueError("minimum performance ratio must be positive")
lp = result(lp_report, "LP")
hp = result(hp_report, "HP")
if lp.get("mode") != hp.get("mode"):
raise ValueError("LP and HP CoreMark reports must use the same mode")
if lp.get("cpu_hz") != hp.get("cpu_hz"):
raise ValueError("LP and HP CoreMark reports must use the same fixed frequency")
try:
lp_score = Decimal(str(lp["coremark_per_mhz"]))
hp_score = Decimal(str(hp["coremark_per_mhz"]))
ratio = hp_score / lp_score
except (InvalidOperation, KeyError, ZeroDivisionError) as error:
raise ValueError("invalid CoreMark/MHz values") from error
passed = ratio >= threshold
return {
"schema_version": 1,
"status": "passed" if passed else "failed",
"frequency_hz": lp["cpu_hz"],
"mode": lp["mode"],
"lp_coremark_per_mhz": str(lp_score),
"hp_coremark_per_mhz": str(hp_score),
"minimum_ratio": str(threshold),
"measured_ratio": str(ratio.quantize(Decimal("0.001"))),
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--lp", type=Path, required=True)
parser.add_argument("--hp", type=Path, required=True)
parser.add_argument("--minimum-ratio", type=Decimal, default=Decimal("2.5"))
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
try:
report = compare(
json.loads(args.lp.read_text(encoding="utf-8")),
json.loads(args.hp.read_text(encoding="utf-8")),
args.minimum_ratio,
)
except (OSError, ValueError, json.JSONDecodeError) as error:
print(f"performance comparison failed: {error}", file=sys.stderr)
return 1
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(
json.dumps(report, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
if report["status"] != "passed":
print(
f"HP/LP CoreMark/MHz ratio {report['measured_ratio']} is below "
f"{report['minimum_ratio']}",
file=sys.stderr,
)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())
+108
View File
@@ -0,0 +1,108 @@
#!/usr/bin/env python3
"""Generate the locked VexiiRiscv HP core below the selected build variant."""
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.GenerateRetroSocHp"
GENERATED_MODULE = "vexii_riscv_hp_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 generate(args: argparse.Namespace) -> None:
root = args.root.resolve()
source = args.source.resolve()
output = args.output.resolve()
expected = locked_revision(args.lock.resolve())
actual = git_revision(source)
if actual != expected:
raise ValueError(f"VexiiRiscv revision mismatch: expected {expected}, found {actual}")
scala_dir = root / "scripts" / "vexiiriscv"
output.mkdir(parents=True, exist_ok=True)
command = [
str(args.sbt),
f'set Compile / unmanagedSourceDirectories += file("{scala_dir}")',
f"runMain {GENERATOR_CLASS} {output}",
]
environment = os.environ.copy()
java_home = environment.get("HOME")
if java_home:
inherited = environment.get("JAVA_TOOL_OPTIONS", "").strip()
environment["JAVA_TOOL_OPTIONS"] = (
f"{inherited} -Duser.home={java_home}".strip()
)
subprocess.run(command, cwd=source, check=True, env=environment)
generated = output / "vexii_riscv_hp_generated.v"
if not generated.is_file():
raise FileNotFoundError(f"VexiiRiscv generator did not create {generated}")
submodules = run(["git", "submodule", "status", "--recursive"], source).splitlines()
manifest = {
"schema_version": 1,
"module": GENERATED_MODULE,
"configuration": "rv32imafdc_max",
"vexiiriscv_revision": actual,
"source_status": git_status(source),
"submodules": submodules,
"generator": str((scala_dir / "GenerateRetroSocHp.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()
+127
View File
@@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""Package LP firmware and the fixed HP Linux image set into one flash image."""
from __future__ import annotations
import argparse
import hashlib
import json
import struct
import zlib
from pathlib import Path
FLASH_SIZE = 16 * 1024 * 1024
BUNDLE_OFFSET = 1 * 1024 * 1024
PAYLOAD_ALIGNMENT = 4096
MAGIC = 0x50485352
VERSION = 1
REQUIRED = 1
HEADER = struct.Struct("<8I")
ENTRY = struct.Struct("<6I")
ARTIFACTS = (
(1, "fw_jump.bin", 0x38000000, 512 * 1024),
(2, "retrosoc_hp.dtb", 0x38080000, 64 * 1024),
(3, "Image", 0x38400000, 12 * 1024 * 1024),
(4, "rootfs.cpio.gz", 0x39000000, 8 * 1024 * 1024),
)
HEADER_SIZE = HEADER.size + (ENTRY.size * len(ARTIFACTS))
def align_up(value: int, alignment: int) -> int:
return (value + alignment - 1) & ~(alignment - 1)
def sha256(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def package(args: argparse.Namespace) -> None:
firmware = args.firmware.read_bytes()
if len(firmware) > BUNDLE_OFFSET:
raise ValueError(
f"LP firmware is {len(firmware)} bytes; bundle starts at {BUNDLE_OFFSET}"
)
payload_offset = align_up(BUNDLE_OFFSET + HEADER_SIZE, PAYLOAD_ALIGNMENT)
entries: list[bytes] = []
payloads: list[tuple[int, bytes]] = []
artifact_manifest: dict[str, object] = {}
cursor = payload_offset
for kind, name, load_address, maximum in ARTIFACTS:
data = (args.images / name).read_bytes()
if not data or len(data) > maximum:
raise ValueError(f"{name} size {len(data)} is outside 1..{maximum} bytes")
crc32 = zlib.crc32(data) & 0xFFFFFFFF
entries.append(ENTRY.pack(kind, cursor, load_address, len(data), crc32, REQUIRED))
payloads.append((cursor, data))
artifact_manifest[name] = {
"crc32": f"0x{crc32:08X}",
"flash_offset": f"0x{cursor:08X}",
"load_address": f"0x{load_address:08X}",
"sha256": sha256(data),
"size_bytes": len(data),
}
cursor = align_up(cursor + len(data), PAYLOAD_ALIGNMENT)
if cursor > FLASH_SIZE:
raise ValueError(f"HP boot image needs {cursor} bytes; flash capacity is {FLASH_SIZE}")
total_size = cursor - BUNDLE_OFFSET
header = HEADER.pack(
MAGIC,
VERSION,
HEADER_SIZE,
len(entries),
total_size,
0,
REQUIRED,
0,
) + b"".join(entries)
header_crc32 = zlib.crc32(header) & 0xFFFFFFFF
header = HEADER.pack(
MAGIC,
VERSION,
HEADER_SIZE,
len(entries),
total_size,
header_crc32,
REQUIRED,
0,
) + b"".join(entries)
image = bytearray(b"\xFF" * cursor)
image[: len(firmware)] = firmware
image[BUNDLE_OFFSET : BUNDLE_OFFSET + len(header)] = header
for offset, data in payloads:
image[offset : offset + len(data)] = data
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_bytes(image)
manifest = {
"schema_version": 1,
"format": "retrosoc-hp-boot-bundle-v1",
"bundle_offset": f"0x{BUNDLE_OFFSET:08X}",
"flash_capacity_bytes": FLASH_SIZE,
"header_crc32": f"0x{header_crc32:08X}",
"image_sha256": sha256(image),
"image_size_bytes": len(image),
"lp_firmware_size_bytes": len(firmware),
"artifacts": artifact_manifest,
}
args.manifest.parent.mkdir(parents=True, exist_ok=True)
args.manifest.write_text(
json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--firmware", type=Path, required=True)
parser.add_argument("--images", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--manifest", type=Path, required=True)
package(parser.parse_args())
if __name__ == "__main__":
main()
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""Install the pinned HP Linux, OpenSBI, and Buildroot source trees."""
from __future__ import annotations
import argparse
import os
import subprocess
from pathlib import Path
from dependency_lock import source
from setup_helpers import ensure_git_repo, run
ROOT = Path(__file__).resolve().parents[1]
def repair_incomplete_checkout(
destination: Path, url: str, revision: str
) -> None:
if not (destination / ".git").is_dir():
return
result = subprocess.run(
["git", "-C", str(destination), "rev-parse", "--verify", "HEAD"],
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
if result.returncode == 0:
return
run(("git", "remote", "set-url", "origin", url), cwd=destination)
run(("git", "fetch", "--depth", "1", "origin", revision), cwd=destination)
run(("git", "checkout", "--detach", "FETCH_HEAD"), cwd=destination)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--update", action="store_true")
args = parser.parse_args()
# The stable Linux mirror is large enough to expose HTTP/2 proxy framing failures.
os.environ.setdefault("GIT_CONFIG_COUNT", "1")
os.environ.setdefault("GIT_CONFIG_KEY_0", "http.version")
os.environ.setdefault("GIT_CONFIG_VALUE_0", "HTTP/1.1")
for name in ("opensbi_hp", "linux_hp", "buildroot_hp"):
dependency = source(name)
destination = ROOT / dependency["destination"]
repair_incomplete_checkout(
destination, dependency["url"], dependency["revision"]
)
ensure_git_repo(
dependency["url"],
destination,
dependency["revision"],
recursive=dependency.get("recursive", False),
update=args.update,
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
+125
View File
@@ -0,0 +1,125 @@
package vexiiriscv
import spinal.core._
import spinal.lib.bus.misc.SizeMapping
import spinal.lib.bus.tilelink.M2sTransfers
import spinal.lib.system.tag.PmaRegionImpl
import vexiiriscv.misc.EmbeddedRiscvJtag
import java.nio.file.{Files, Paths}
/** Generates the fixed retroSoC RV32 Linux application core. */
object GenerateRetroSocHp extends App {
require(args.length == 1, "usage: GenerateRetroSocHp <output-directory>")
val output = Paths.get(args(0)).toAbsolutePath.normalize
Files.createDirectories(output)
val param = new ParamSimple()
param.xlen = 32
param.physicalWidth = 32
param.resetVector = 0x38000000L
param.asidWidth = 9
param.addISA("m", "a", "f", "d", "c", "s", "u", "zicntr", "zihpm")
param.fixIsaParams()
param.decoders = 2
param.lanes = 2
param.withBtb = true
param.withGShare = true
param.withRas = true
param.withLateAlu = true
param.withAlignerBuffer = true
param.withDispatcherBuffer = true
param.allowBypassFrom = 0
param.storeRs2Late = true
param.divRadix = 4
param.divArea = false
param.fetchL1Enable = true
param.fetchL1Sets = 64
param.fetchL1Ways = 4
param.fetchMemDataWidthMin = 64
param.fetchL1RefillCount = 2
param.fetchL1Prefetch = "nl"
param.fetchBus = FetchBusEnum.axi4
param.lsuL1Enable = true
param.lsuL1Sets = 64
param.lsuL1Ways = 4
param.lsuMemDataWidthMin = 64
param.lsuL1RefillCount = 8
param.lsuL1WritebackCount = 8
param.lsuStoreBufferSlots = 4
param.lsuStoreBufferOps = 32
param.lsuSoftwarePrefetch = true
param.lsuHardwarePrefetch = "rpt"
param.withLsuBypass = true
param.lsuBus = LsuBusEnum.axi4
param.lsuL1Bus = LsuL1BusEnum.axi4
param.pmpParam.pmpSize = 16
param.pmpParam.granularity = 4096
param.additionalPerformanceCounters = 8
param.privParam.withRdTime = true
param.privParam.withDebug = true
param.privParam.debugTriggers = 4
param.embeddedJtagTap = true
val config = SpinalConfig(
targetDirectory = output.toString,
inlineRom = true
)
config.generateVerilog {
val plugins = param.plugins(hartId = 1)
plugins.foreach {
case plugin: EmbeddedRiscvJtag =>
plugin.debugCd = ClockDomain.current.copy(
reset = Bool().setName("EmbeddedRiscvJtag_logic_debug_reset")
)
case _ =>
}
ParamSimple.setPma(
plugins,
Seq(
new PmaRegionImpl(
mapping = SizeMapping(0x00000000L, 0x01000000L),
isMain = false,
isExecutable = true,
transfers = M2sTransfers.all
),
new PmaRegionImpl(
mapping = SizeMapping(0x02000000L, 0x2E000000L),
isMain = false,
isExecutable = false,
transfers = M2sTransfers.all
),
new PmaRegionImpl(
mapping = SizeMapping(0x30000000L, 0x00020000L),
isMain = true,
isExecutable = true,
transfers = M2sTransfers.all
),
new PmaRegionImpl(
mapping = SizeMapping(0x38000000L, 0x04000000L),
isMain = true,
isExecutable = true,
transfers = M2sTransfers.all
),
new PmaRegionImpl(
mapping = SizeMapping(0x40000000L, 0x02000000L),
isMain = true,
isExecutable = true,
transfers = M2sTransfers.all
),
new PmaRegionImpl(
mapping = SizeMapping(0x48000000L, 0x08000000L),
isMain = true,
isExecutable = true,
transfers = M2sTransfers.all
)
)
)
VexiiRiscv(plugins).setDefinitionName("vexii_riscv_hp_generated")
}
}