130 lines
4.7 KiB
Python
130 lines
4.7 KiB
Python
__all__ = ["picker_export"]
|
|
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
from tempfile import NamedTemporaryFile
|
|
|
|
from toffee_test.markers import match_version
|
|
|
|
from .cfg.model import UnityChipConfig
|
|
|
|
|
|
def picker_export(
|
|
source_name: str,
|
|
cfg: UnityChipConfig,
|
|
target_name: str = "",
|
|
simulator: str = "verilator",
|
|
access_mode: int = 0,
|
|
internal_file: str = "",
|
|
vflags="",
|
|
cflags="",
|
|
rtl_version: str | list[str] = "openxiangshan-kmh-*",
|
|
) -> bool:
|
|
"""Export RTL module to Python DUT using picker tool.
|
|
|
|
This function exports a specified RTL module to a Python Design Under Test (DUT)
|
|
class using the picker export tool. It handles dependency resolution, simulator
|
|
configuration, and various export options including waveform generation and
|
|
code coverage.
|
|
|
|
Args:
|
|
source_name: Name of the top-level RTL module to export. Cannot be empty.
|
|
cfg: Configuration object.
|
|
target_name: Name for the exported DUT class. Defaults to source_name if empty.
|
|
simulator: Simulator to use for the export. Options include "verilator", "vcs".
|
|
Defaults to "verilator".
|
|
access_mode: Memory access mode. 0 for VPI mode, 1 for Mem-Direct mode.
|
|
Mem-Direct mode only supports verilator. Defaults to 0.
|
|
internal_file: Path to a YAML file containing internal signals to export to DUT class.
|
|
Optional.
|
|
vflags: Additional flags to pass to the simulator.
|
|
cflags: Additional C++ compilation flags to pass to the compiler.
|
|
rtl_version: Required RTL version pattern(s). Can be a string or list of strings.
|
|
Defaults to "openxiangshan-kmh-*".
|
|
|
|
Returns:
|
|
bool: True if export was successful, False otherwise.
|
|
|
|
Raises:
|
|
AssertionError: If source_name is empty, if no RTL files are found for the module,
|
|
or if Mem-Direct mode is used with a simulator other than verilator.
|
|
|
|
Note:
|
|
- Waveform format is automatically selected based on simulator: fst for verilator,
|
|
fsdb for vcs, vcd for others
|
|
- The exported DUT is placed in the {root}/dut directory
|
|
- RTL version compatibility is checked before export
|
|
"""
|
|
from comm import get_root_dir, error, get_all_rtl_files, info
|
|
|
|
assert source_name, "Cannot export DUT without module name"
|
|
|
|
if not match_version(cfg.rtl.version, rtl_version):
|
|
error(f"(Export {source_name}): Unsupported RTL version {cfg.rtl.version}")
|
|
return False
|
|
|
|
# Get all dependencies
|
|
dependencies = get_all_rtl_files(source_name, cfg)
|
|
assert dependencies, f"Cannot found any rtl for {source_name}"
|
|
|
|
# Mem-Direct mode only supports verilator
|
|
if access_mode == 1:
|
|
assert simulator == "verilator", "Mem-Direct mode only supports verilator as simulator"
|
|
|
|
# If target name is set
|
|
if not target_name:
|
|
target_name = source_name
|
|
|
|
# Picker export command
|
|
cmd = [
|
|
shutil.which('picker'), # Picker export subcommand
|
|
"export",
|
|
dependencies[0], # Path of the top module
|
|
"--autobuild", "1",
|
|
"--lang", "python", # Export language is python
|
|
"--cp_lib", "0", # Disable copy xspcomm library
|
|
"--sim", simulator, # Set simulator
|
|
"--rw", str(access_mode), # Set access-mode
|
|
"--sname", source_name, # Top module name to export
|
|
"--tdir", get_root_dir("dut") + "/", # Export to %{root}/dut dir
|
|
"--tname", target_name,
|
|
]
|
|
|
|
# Waveform format
|
|
wave_format = ""
|
|
if simulator == "verilator":
|
|
wave_format = "fst"
|
|
elif simulator == "vcs":
|
|
wave_format = "fsdb"
|
|
else:
|
|
wave_format = "vcd"
|
|
|
|
# Enable waveform
|
|
if not cfg.no_waveform:
|
|
cmd.extend(["-w", ".".join((target_name, wave_format))])
|
|
# Enable code coverage
|
|
if cfg.no_code_cov is not None and cfg.no_code_cov == False:
|
|
cmd.append("-c")
|
|
# Export internal signals to DUT class
|
|
if internal_file:
|
|
internal_path = os.path.join(get_root_dir(internal_file))
|
|
assert os.path.exists(internal_path), "Internal file not found"
|
|
cmd.extend(["--internal", internal_path])
|
|
# Add Flags
|
|
if vflags:
|
|
cmd.extend(["-V", vflags])
|
|
if cflags:
|
|
cmd.extend(["-C", cflags])
|
|
|
|
with NamedTemporaryFile(mode="w+", encoding="utf-8", suffix=".txt") as filelist:
|
|
info("Exporting %s", source_name)
|
|
cmd.extend(["--fs", filelist.name])
|
|
filelist.write("\n".join(dependencies))
|
|
filelist.flush()
|
|
# Execute picker export to generate DUT
|
|
ret = subprocess.run(cmd, shell=False, stderr=subprocess.PIPE)
|
|
if ret.returncode:
|
|
error(f"Failed to export:\n {ret.stderr}")
|
|
return ret.returncode == 0
|