Add Compilation Script
Script Target
Write a compilation file for the corresponding RTL in the scripts
directory using Python (e.g., build_ut_frontend_ifu_rvc_expander.py
).
The goal of this script is to provide RTL-to-Python DUT compilation, target coverage files, and custom functionality.
Creation Process
Determine File Name
Select the UT to be verified in XiangShan Kunming Lake DUT Verification Progress. If it is not available or needs further refinement, you can manually add it by editing configs/dutree/xiangshan-kmh.yaml
.
For example, if we want to verify the rvc_expander
module under the ifu
module in the frontend, we need to add the corresponding part to configs/dutree/xiangshan-kmh.yaml
(this module already exists in the YAML file; this is just an example):
name: "kmh_dut"
desc: "All Kunming Lake DUTs"
children:
- name: "frontend"
desc: "Frontend Module"
children:
- name: "ifu"
desc: "Instruction Fetch Unit"
children:
- name: "rvc_expander"
desc: "RVC Instruction Expander"
The naming format for the script file is as follows:
scripts/build_<top_module>_<sub_module>_..._<target_module>.py
Currently, the project includes four top-level modules:
- ut_frontend (Frontend)
- ut_backend (Backend)
- ut_mem_block (Memory Access)
- ut_misc (Miscellaneous)
Submodules do not have the ut_
prefix (the top-level directories have this prefix to distinguish them from other directories).
For example, if the target DUT to be verified is the rvc_expander
module:
This module belongs to the frontend, so the top-level module is ut_frontend
. Its submodule is ifu
, and the target module is rvc_expander
.
From the previously opened yaml
file, we can also see that the children
of frontend
is ifu
, and the children
of ifu
is rvc_expander
.
Thus, the script name to be created is build_ut_frontend_ifu_rvc_expander.py
.
Write the build(cfg) -> bool
Function
The build
function is defined as follows:
def build(cfg) -> bool:
"""Compile DUT
Args:
cfg: Runtime configuration, which can be used to access configuration items, e.g., cfg.rtl.version
Return:
Returns True or False, indicating whether the function achieved its intended goal
"""
The build
function is called during make dut
. Its main purpose is to convert the target RTL into a Python module. Other necessary processes, such as compiling dependencies, can also be added. For example, in build_ut_frontend_ifu_rvc_expander.py
, the function primarily performs RTL checks, DUT checks, RTL compilation, and disasm dependency compilation:
import os
from comm import warning, info
def build(cfg):
# Import related dependencies
from toffee_test.markers import match_version
from comm import is_all_file_exist, get_rtl_dir, exe_cmd, get_root_dir
# Check RTL version (an empty version parameter means all versions are supported)
if not match_version(cfg.rtl.version, "openxiangshan-kmh-*"):
warning("ifu frontend rvc expander: %s" % f"Unsupported RTL version {cfg.rtl.version}")
return False
# Check if the target file exists in the current RTL
f = is_all_file_exist(["rtl/RVCExpander.sv"], get_rtl_dir(cfg=cfg))
assert f is True, f"File {f} not found"
# If the DUT does not contain RVCExpander, use picker to package it into Python
if not os.path.exists(get_root_dir("dut/RVCExpander")):
info("Exporting RVCExpander.sv")
s, out, err = exe_cmd(f'picker export --cp_lib false {get_rtl_dir("rtl/RVCExpander.sv", cfg=cfg)} --lang python --tdir {get_root_dir("dut")}/ -w rvc.fst -c')
assert s, "Failed to export RVCExpander.sv: %s\n%s" % (out, err)
# If disasm/build does not exist in tools, compile disasm
if not os.path.exists(get_root_dir("tools/disasm/build")):
info("Building disasm")
s, _, _ = exe_cmd("make -C %s" % get_root_dir("tools/disasm"))
assert s, "Failed to build disasm"
# Compilation successful
return True
def line_coverage_files(cfg):
return ["RVCExpander.v"]
For details on how to use picker
, refer to its documentation and usage guide.
In the scripts
directory, you can create subdirectories to store files needed for UT verification. For example, the rvc_expander
module creates a scripts/frontend_ifu_rvc_expander
directory, where rtl_file.f
specifies the input RTL file, and line_coverage.ignore
stores lines of code to be ignored in coverage statistics. Custom directory names should be reasonable and should indicate the module and file they belong to.
Write the line_coverage_files(cfg) -> list[str]
Function
The line_coverage_files
function is defined as follows:
def line_coverage_files(cfg) -> list[str]:
"""Specify files to be covered
Args:
cfg: Runtime configuration, which can be used to access configuration items, e.g., cfg.rtl.version
Return:
Returns the names of RTL files targeted for line coverage statistics
"""
In the build_ut_frontend_ifu_rvc_expander.py
file, the line_coverage_files
function is defined as follows:
def line_coverage_files(cfg):
return ["RVCExpander.v"]
This indicates that the module focuses on coverage for the RVCExpander.v
file. If you want to enable test result processing, set disable=False
under doc-result
in configs/_default.yaml
(the default parameter is False
, meaning it is enabled). If you do not enable test result processing (disable=True
), the above function will not be called.