|
30 | 30 | from dvsim.modes import BuildMode |
31 | 31 | from dvsim.sim.flow import SimCfg |
32 | 32 |
|
33 | | - |
34 | 33 | __all__ = ( |
35 | 34 | "CompileSim", |
| 35 | + "CovVPlan", |
36 | 36 | "Deploy", |
37 | 37 | ) |
38 | 38 |
|
@@ -1028,3 +1028,88 @@ def _set_attrs(self) -> None: |
1028 | 1028 | self.qual_name = self.target |
1029 | 1029 | self.full_name = f"{self.sim_cfg.name}{self._variant_suffix}:{self.qual_name}" |
1030 | 1030 | self.input_dirs += [self.cov_merge_db_dir] |
| 1031 | + |
| 1032 | + |
| 1033 | +class CovVPlan(Deploy): |
| 1034 | + """Abstraction for generating a Verification Plan (vPlan) report using DVPlan.""" |
| 1035 | + |
| 1036 | + target = "cov_vplan" |
| 1037 | + weight = 10 |
| 1038 | + |
| 1039 | + def __init__(self, cov_report_job, sim_cfg) -> None: |
| 1040 | + self.report_job = cov_report_job |
| 1041 | + super().__init__(sim_cfg) |
| 1042 | + self.dependencies.append(cov_report_job) |
| 1043 | + |
| 1044 | + def _define_attrs(self) -> None: |
| 1045 | + super()._define_attrs() |
| 1046 | + self.mandatory_cmd_attrs.update( |
| 1047 | + { |
| 1048 | + "proj_root": False, |
| 1049 | + "vplan": False, |
| 1050 | + } |
| 1051 | + ) |
| 1052 | + self.mandatory_misc_attrs.update( |
| 1053 | + { |
| 1054 | + "dut_instance": False, |
| 1055 | + } |
| 1056 | + ) |
| 1057 | + |
| 1058 | + def _set_attrs(self) -> None: |
| 1059 | + self.cov_vplan_dir = f"{self.sim_cfg.scratch_path}/{self.target}" |
| 1060 | + |
| 1061 | + super()._set_attrs() |
| 1062 | + self.qual_name = self.target |
| 1063 | + self.full_name = f"{self.sim_cfg.name}{self._variant_suffix}:{self.qual_name}" |
| 1064 | + |
| 1065 | + self.prepare_opts = self.sim_cfg.cov_vplan_prepare_opts |
| 1066 | + self.process_opts = self.sim_cfg.cov_vplan_process_opts |
| 1067 | + |
| 1068 | + # Calculate IP root and derive the stem used to name output files. |
| 1069 | + vplan_path = Path(self.vplan) |
| 1070 | + self.ip_root = str(vplan_path.parent.parent) |
| 1071 | + vplan_stem = vplan_path.stem |
| 1072 | + |
| 1073 | + # Determine paths for the intermediate HJSON and the final HTML report. |
| 1074 | + # Use the vplan filename stem so the outputs are named after the plan |
| 1075 | + # (e.g. "rv_timer_vplan_annotated.hjson") rather than the sim name. |
| 1076 | + self.annotated_hjson = f"{self.odir}/{vplan_stem}_annotated.hjson" |
| 1077 | + self.gen_html = f"{self.odir}/{vplan_stem}_annotated.html" |
| 1078 | + self.output_dirs = [self.odir] |
| 1079 | + |
| 1080 | + def _construct_cmd(self) -> str: |
| 1081 | + """Construct the pure bash shell command, bypassing the base Makefile assumption.""" |
| 1082 | + import shlex |
| 1083 | + import shutil |
| 1084 | + |
| 1085 | + if shutil.which("dvplan") is None: |
| 1086 | + fallback = ( |
| 1087 | + "echo 'WARNING: dvplan tool not installed in PATH. Skipping vPlan generation.'" |
| 1088 | + ) |
| 1089 | + return f"/usr/bin/env bash -c {shlex.quote(fallback)}" |
| 1090 | + |
| 1091 | + plugin = get_sim_tool_plugin(tool=self.sim_cfg.tool) |
| 1092 | + |
| 1093 | + def format_opts(opts): |
| 1094 | + return " ".join(opts) if isinstance(opts, list) else str(opts) |
| 1095 | + |
| 1096 | + prepare_opts_str = format_opts(self.prepare_opts) |
| 1097 | + process_opts_str = format_opts(self.process_opts) |
| 1098 | + |
| 1099 | + prepare_cmd = f"dvplan prepare_vplan {prepare_opts_str} {self.ip_root} {self.vplan} {self.annotated_hjson}" |
| 1100 | + prepare_cmd = " ".join(prepare_cmd.split()) |
| 1101 | + |
| 1102 | + vendor_tool = f"{self.sim_cfg.tool}_report" |
| 1103 | + cov_report_txt = getattr(self.report_job, "cov_report_txt", "") |
| 1104 | + report_path = plugin.get_dvplan_report_path( |
| 1105 | + cov_report_dir=self.report_job.cov_report_dir, cov_report_txt=cov_report_txt |
| 1106 | + ) |
| 1107 | + |
| 1108 | + process_cmd = ( |
| 1109 | + f"dvplan process_results {process_opts_str} --coverage {vendor_tool} {report_path} " |
| 1110 | + f"-R {self.gen_html} -s {self.sim_cfg.name} {self.dut_instance} {self.annotated_hjson}" |
| 1111 | + ) |
| 1112 | + process_cmd = " ".join(process_cmd.split()) |
| 1113 | + |
| 1114 | + full_command = f"set -e; mkdir -p {self.odir}; {prepare_cmd} && {process_cmd}" |
| 1115 | + return f"/usr/bin/env bash -c {shlex.quote(full_command)}" |
0 commit comments