diff --git a/src/dvsim/cli/admin.py b/src/dvsim/cli/admin.py index 4725f07..0ced939 100644 --- a/src/dvsim/cli/admin.py +++ b/src/dvsim/cli/admin.py @@ -35,9 +35,9 @@ def report() -> None: ) def gen(json_path: Path, output_dir: Path) -> None: """Generate a report from a existing results JSON.""" - from dvsim.report.data import ResultsSummary - from dvsim.report.generate import gen_reports + from dvsim.sim.data import SimResultsSummary + from dvsim.sim.report import gen_reports - results: ResultsSummary = ResultsSummary.load(path=json_path) + results: SimResultsSummary = SimResultsSummary.load(path=json_path) gen_reports(summary=results, path=output_dir) diff --git a/src/dvsim/flow/base.py b/src/dvsim/flow/base.py index f5c5b86..7cbd59e 100644 --- a/src/dvsim/flow/base.py +++ b/src/dvsim/flow/base.py @@ -10,7 +10,6 @@ import sys from abc import ABC, abstractmethod from collections.abc import Mapping, Sequence -from datetime import datetime, timezone from pathlib import Path from typing import TYPE_CHECKING, ClassVar @@ -20,15 +19,12 @@ from dvsim.job.data import CompletedJobStatus from dvsim.launcher.factory import get_launcher_cls from dvsim.logging import log -from dvsim.report.data import FlowResults, IPMeta, ResultsSummary -from dvsim.report.generate import gen_block_report, gen_reports from dvsim.scheduler import Scheduler from dvsim.utils import ( find_and_substitute_wildcards, rm_path, subst_wildcards, ) -from dvsim.utils.git import git_commit_hash if TYPE_CHECKING: from dvsim.job.deploy import Deploy @@ -447,6 +443,7 @@ def deploy_objects(self) -> Sequence[CompletedJobStatus]: interactive=self.interactive, ).run() + @abstractmethod def gen_results(self, results: Sequence[CompletedJobStatus]) -> None: """Generate flow results. @@ -454,68 +451,6 @@ def gen_results(self, results: Sequence[CompletedJobStatus]) -> None: results: completed job status objects. """ - reports_dir = Path(self.scratch_base_path) / "reports" - commit = git_commit_hash(path=Path(self.proj_root)) - url = f"https://github.com/lowrisc/opentitan/tree/{commit}" - - all_flow_results: Mapping[str, FlowResults] = {} - - for item in self.cfgs: - item_results = [ - res - for res in results - if res.block.name == item.name and res.block.variant == item.variant - ] - - flow_results: FlowResults = item._gen_json_results( - run_results=item_results, - commit=commit, - url=url, - ) - - # Convert to lowercase to match filename - block_result_index = ( - f"{item.name}_{item.variant}" if item.variant else item.name - ).lower() - - all_flow_results[block_result_index] = flow_results - - # Generate the block's JSON/HTML reports to the report area. - gen_block_report( - results=flow_results, - path=reports_dir, - ) - - self.errors_seen |= item.errors_seen - - if self.is_primary_cfg: - # The timestamp for this run has been taken with `utcnow()` and is - # stored in a custom format. Store it in standard ISO format with - # explicit timezone annotation. - timestamp = ( - datetime.strptime(self.timestamp, "%Y%m%d_%H%M%S") - .replace(tzinfo=timezone.utc) - .isoformat() - ) - - results_summary = ResultsSummary( - top=IPMeta( - name=self.name, - variant=self.variant, - commit=commit, - branch=self.branch, - url=url, - ), - timestamp=timestamp, - flow_results=all_flow_results, - report_path=reports_dir, - ) - - # Generate all the JSON/HTML reports to the report area. - gen_reports( - summary=results_summary, - path=reports_dir, - ) def has_errors(self) -> bool: """Return error state.""" diff --git a/src/dvsim/flow/factory.py b/src/dvsim/flow/factory.py index 11b88a2..166db15 100644 --- a/src/dvsim/flow/factory.py +++ b/src/dvsim/flow/factory.py @@ -11,9 +11,9 @@ from dvsim.flow.hjson import load_hjson from dvsim.flow.lint import LintCfg from dvsim.flow.rdc import RdcCfg -from dvsim.flow.sim import SimCfg from dvsim.flow.syn import SynCfg from dvsim.logging import log +from dvsim.sim.flow import SimCfg FLOW_HANDLERS = { "cdc": CdcCfg, diff --git a/src/dvsim/flow/lint.py b/src/dvsim/flow/lint.py index 66f7243..a342f67 100644 --- a/src/dvsim/flow/lint.py +++ b/src/dvsim/flow/lint.py @@ -76,7 +76,10 @@ def gen_results_summary(self): keys = self.totals.get_keys(self.report_severities) for cfg in self.cfgs: - name_with_link = cfg._get_results_page_link(self.results_dir) + link_text = self.name.upper() + relative_link = Path(self.results_dir) / self.results_page + + name_with_link = f"[{link_text}]({relative_link})" row = [name_with_link] row += cfg.result_summary.get_counts_md(keys) diff --git a/src/dvsim/flow/one_shot.py b/src/dvsim/flow/one_shot.py index ea8dc15..c73b3ea 100644 --- a/src/dvsim/flow/one_shot.py +++ b/src/dvsim/flow/one_shot.py @@ -4,10 +4,13 @@ """Class describing a one-shot build configuration object.""" -import pathlib +from abc import abstractmethod from collections import OrderedDict +from collections.abc import Sequence +from pathlib import Path from dvsim.flow.base import FlowCfg +from dvsim.job.data import CompletedJobStatus from dvsim.job.deploy import CompileOneShot from dvsim.logging import log from dvsim.modes import BuildMode, Mode @@ -15,9 +18,7 @@ class OneShotCfg(FlowCfg): - """Simple one-shot build flow for non-simulation targets like - linting, synthesis and FPV. - """ + """Simple one-shot build flow for non-simulation targets like linting, synthesis and FPV.""" ignored_wildcards = [*FlowCfg.ignored_wildcards, "build_mode", "index", "test"] @@ -134,8 +135,10 @@ def _print_list(self) -> None: def _create_dirs(self) -> None: """Create initial set of directories.""" for link in self.links: - rm_path(self.links[link]) - pathlib.Path(self.links[link]).mkdir(parents=True) + link_path = Path(self.links[link]) + + rm_path(link_path) + link_path.mkdir(parents=True) def _create_deploy_objects(self) -> None: """Create deploy objects from build modes.""" @@ -149,3 +152,49 @@ def _create_deploy_objects(self) -> None: # Create initial set of directories before kicking off the regression. self._create_dirs() + + @abstractmethod + def _gen_results(self): + """Generate results for this config.""" + + @abstractmethod + def gen_results_summary(self): + """Gathers the aggregated results from all sub configs.""" + + def gen_results(self, results: Sequence[CompletedJobStatus]) -> None: + """Generate flow results. + + Args: + results: completed job status objects. + + """ + for item in self.cfgs: + project = item.name + + item_results = [ + res + for res in results + if res.block.name == item.name and res.block.variant == item.variant + ] + + result = item._gen_results(item_results) + + log.info("[results]: [%s]:\n%s\n", project, result) + log.info("[scratch_path]: [%s] [%s]", project, item.scratch_path) + + # TODO: Implement HTML report using templates + + results_dir = Path(self.results_dir) + results_dir.mkdir(exist_ok=True, parents=True) + + # (results_dir / self.results_html_name).write_text( + # md_results_to_html(self.results_title, self.css_file, item.results_md) + # ) + + log.verbose("[report]: [%s] [%s/report.html]", project, item.results_dir) + + self.errors_seen |= item.errors_seen + + if self.is_primary_cfg: + self.gen_results_summary() + # self.write_results(self.results_html_name, self.results_summary_md) diff --git a/src/dvsim/job/deploy.py b/src/dvsim/job/deploy.py index 83f949b..9a55d8b 100644 --- a/src/dvsim/job/deploy.py +++ b/src/dvsim/job/deploy.py @@ -74,6 +74,10 @@ def __init__(self, sim_cfg: "SimCfg") -> None: # Cross ref the whole cfg object for ease. self.sim_cfg = sim_cfg self.flow = sim_cfg.name + + if not hasattr(self.sim_cfg, "variant"): + self.sim_cfg.variant = "" + self._variant_suffix = f"_{self.sim_cfg.variant}" if self.sim_cfg.variant else "" # A list of jobs on which this job depends. diff --git a/src/dvsim/launcher/base.py b/src/dvsim/launcher/base.py index db42c8b..f361591 100644 --- a/src/dvsim/launcher/base.py +++ b/src/dvsim/launcher/base.py @@ -339,25 +339,28 @@ def _find_patterns(patterns: Sequence[str], line: str) -> Sequence[str] | None: # since it is devoid of the delays incurred due to infrastructure and # setup overhead. - plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name) + time = self.job_runtime_secs + unit = "s" + + if self.job_spec.job_type in [ + "CompileSim", + "RunTest", + "CovUnr", + "CovMerge", + "CovReport", + "CovAnalyze", + ]: + plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name) - try: - time, unit = plugin.get_job_runtime(log_text=lines) - self.job_runtime.set(time, unit) - - except RuntimeError as e: - log.warning( - f"{self.job_spec.full_name}: {e} Using dvsim-maintained job_runtime instead." - ) - self.job_runtime.set(self.job_runtime_secs, "s") - - if self.job_spec.job_type == "RunTest": try: - time, unit = plugin.get_simulated_time(log_text=lines) - self.simulated_time.set(time, unit) + time, unit = plugin.get_job_runtime(log_text=lines) except RuntimeError as e: - log.debug(f"{self.job_spec.full_name}: {e}") + log.warning( + f"{self.job_spec.full_name}: {e} Using dvsim-maintained job_runtime instead." + ) + + self.job_runtime.set(time, unit) if chk_failed or chk_passed: for cnt, line in enumerate(lines): diff --git a/src/dvsim/report/data.py b/src/dvsim/report/data.py index f4a518c..829d20a 100644 --- a/src/dvsim/report/data.py +++ b/src/dvsim/report/data.py @@ -4,17 +4,11 @@ """Report data models.""" -from collections.abc import Mapping -from datetime import datetime -from pathlib import Path - from pydantic import BaseModel, ConfigDict -from dvsim.sim_results import BucketedFailures - __all__ = ( "IPMeta", - "ResultsSummary", + "ToolMeta", ) @@ -45,197 +39,3 @@ class ToolMeta(BaseModel): """Name of the tool.""" version: str """Version of the tool.""" - - -class TestResult(BaseModel): - """Test result.""" - - model_config = ConfigDict(frozen=True, extra="forbid") - - max_time: float - """Run time.""" - sim_time: float - """Simulation time.""" - - passed: int - """Number of tests passed.""" - total: int - """Total number of tests run.""" - percent: float - """Percentage test pass rate.""" - - -class Testpoint(BaseModel): - """Testpoint.""" - - model_config = ConfigDict(frozen=True, extra="forbid") - - tests: Mapping[str, TestResult] - """Test results.""" - - passed: int - """Number of tests passed.""" - total: int - """Total number of tests run.""" - percent: float - """Percentage test pass rate.""" - - -class TestStage(BaseModel): - """Test stages.""" - - model_config = ConfigDict(frozen=True, extra="forbid") - - testpoints: Mapping[str, Testpoint] - """Results by test point.""" - - passed: int - """Number of tests passed.""" - total: int - """Total number of tests run.""" - percent: float - """Percentage test pass rate.""" - - -class CodeCoverageMetrics(BaseModel): - """CodeCoverage metrics.""" - - model_config = ConfigDict(frozen=True, extra="forbid") - - block: float | None - """Block Coverage (%) - did this part of the code execute?""" - line_statement: float | None - """Line/Statement Coverage (%) - did this part of the code execute?""" - branch: float | None - """Branch Coverage (%) - did this if/case take all paths?""" - condition_expression: float | None - """Condition/Expression Coverage (%) - did the logic evaluate to 0 & 1?""" - toggle: float | None - """Toggle Coverage (%) - did the signal wiggle?""" - fsm: float | None - """FSM Coverage (%) - did the state machine transition?""" - - @property - def average(self) -> float | None: - """Average code coverage (%).""" - all_cov = [ - c - for c in [ - self.line_statement, - self.branch, - self.condition_expression, - self.toggle, - self.fsm, - ] - if c is not None - ] - - if len(all_cov) == 0: - return None - - return sum(all_cov) / len(all_cov) - - -class CoverageMetrics(BaseModel): - """Coverage metrics.""" - - code: CodeCoverageMetrics | None - """Code Coverage.""" - assertion: float | None - """Assertion Coverage.""" - functional: float | None - """Functional coverage.""" - - @property - def average(self) -> float | None: - """Average code coverage (%) or None if there is no coverage.""" - code = self.code.average if self.code is not None else None - all_cov = [ - c - for c in [ - code, - self.assertion, - self.functional, - ] - if c is not None - ] - - if len(all_cov) == 0: - return None - - return sum(all_cov) / len(all_cov) - - -class FlowResults(BaseModel): - """Flow results data.""" - - model_config = ConfigDict(frozen=True, extra="forbid") - - block: IPMeta - """IP block metadata.""" - tool: ToolMeta - """Tool used in the simulation run.""" - timestamp: datetime - """Timestamp for when the test ran.""" - - stages: Mapping[str, TestStage] - """Results per test stage.""" - coverage: CoverageMetrics | None - """Coverage metrics.""" - - failed_jobs: BucketedFailures - """Bucketed failed job overview.""" - - passed: int - """Number of tests passed.""" - total: int - """Total number of tests run.""" - percent: float - """Percentage test pass rate.""" - - @staticmethod - def load(path: Path) -> "FlowResults": - """Load results from JSON file. - - Transform the fields of the loaded JSON into a more useful schema for - report generation. - - Args: - path: to the json file to load. - - """ - return FlowResults.model_validate_json(path.read_text()) - - -class ResultsSummary(BaseModel): - """Summary of results.""" - - model_config = ConfigDict(frozen=True, extra="forbid") - - top: IPMeta - """Meta data for the top level config.""" - - timestamp: datetime - """Run time stamp.""" - - flow_results: Mapping[str, FlowResults] - """Flow results.""" - - report_path: Path - """Path to the report JSON file.""" - - @staticmethod - def load(path: Path) -> "ResultsSummary": - """Load results from JSON file. - - Transform the fields of the loaded JSON into a more useful schema for - report generation. - - Args: - path: to the json file to load. - - Returns: - The loaded ResultsSummary from JSON. - - """ - return ResultsSummary.model_validate_json(path.read_text()) diff --git a/src/dvsim/sim/__init__.py b/src/dvsim/sim/__init__.py new file mode 100644 index 0000000..4d8f282 --- /dev/null +++ b/src/dvsim/sim/__init__.py @@ -0,0 +1,5 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +"""Simulation workflow.""" diff --git a/src/dvsim/sim/data.py b/src/dvsim/sim/data.py new file mode 100644 index 0000000..da6beef --- /dev/null +++ b/src/dvsim/sim/data.py @@ -0,0 +1,259 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +"""Simulation data models.""" + +from collections.abc import Mapping +from datetime import datetime +from pathlib import Path + +from pydantic import BaseModel, ConfigDict + +from dvsim.report.data import IPMeta, ToolMeta +from dvsim.sim_results import BucketedFailures + +__all__ = ( + "CodeCoverageMetrics", + "CoverageMetrics", + "SimFlowResults", + "SimResultsSummary", + "TestResult", + "TestStage", + "Testpoint", +) + + +class TestResult(BaseModel): + """Test result.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + max_time: float + """Run time.""" + sim_time: float + """Simulation time.""" + + passed: int + """Number of tests passed.""" + total: int + """Total number of tests run.""" + percent: float + """Percentage test pass rate.""" + + +class Testpoint(BaseModel): + """Testpoint.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + tests: Mapping[str, TestResult] + """Test results.""" + + passed: int + """Number of tests passed.""" + total: int + """Total number of tests run.""" + percent: float + """Percentage test pass rate.""" + + +class TestStage(BaseModel): + """Test stages.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + testpoints: Mapping[str, Testpoint] + """Results by test point.""" + + passed: int + """Number of tests passed.""" + total: int + """Total number of tests run.""" + percent: float + """Percentage test pass rate.""" + + +class CodeCoverageMetrics(BaseModel): + """CodeCoverage metrics.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + block: float | None + """Block Coverage (%) - did this part of the code execute?""" + line_statement: float | None + """Line/Statement Coverage (%) - did this part of the code execute?""" + branch: float | None + """Branch Coverage (%) - did this if/case take all paths?""" + condition_expression: float | None + """Condition/Expression Coverage (%) - did the logic evaluate to 0 & 1?""" + toggle: float | None + """Toggle Coverage (%) - did the signal wiggle?""" + fsm: float | None + """FSM Coverage (%) - did the state machine transition?""" + + @property + def average(self) -> float | None: + """Average code coverage (%).""" + all_cov = [ + c + for c in [ + self.line_statement, + self.branch, + self.condition_expression, + self.toggle, + self.fsm, + ] + if c is not None + ] + + if len(all_cov) == 0: + return None + + return sum(all_cov) / len(all_cov) + + +class CoverageMetrics(BaseModel): + """Coverage metrics.""" + + code: CodeCoverageMetrics | None + """Code Coverage.""" + assertion: float | None + """Assertion Coverage.""" + functional: float | None + """Functional coverage.""" + + @property + def average(self) -> float | None: + """Average code coverage (%) or None if there is no coverage.""" + code = self.code.average if self.code is not None else None + all_cov = [ + c + for c in [ + code, + self.assertion, + self.functional, + ] + if c is not None + ] + + if len(all_cov) == 0: + return None + + return sum(all_cov) / len(all_cov) + + +class FlowResults(BaseModel): + """Flow results data.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + block: IPMeta + """IP block metadata.""" + tool: ToolMeta + """Tool used in the simulation run.""" + timestamp: datetime + """Timestamp for when the test ran.""" + + stages: Mapping[str, TestStage] + """Results per test stage.""" + coverage: CoverageMetrics | None + """Coverage metrics.""" + + failed_jobs: BucketedFailures + """Bucketed failed job overview.""" + + passed: int + """Number of tests passed.""" + total: int + """Total number of tests run.""" + percent: float + """Percentage test pass rate.""" + + @staticmethod + def load(path: Path) -> "FlowResults": + """Load results from JSON file. + + Transform the fields of the loaded JSON into a more useful schema for + report generation. + + Args: + path: to the json file to load. + + """ + return FlowResults.model_validate_json(path.read_text()) + + +class SimFlowResults(BaseModel): + """Flow results data.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + block: IPMeta + """IP block metadata.""" + tool: ToolMeta + """Tool used in the simulation run.""" + timestamp: datetime + """Timestamp for when the test ran.""" + + stages: Mapping[str, TestStage] + """Results per test stage.""" + coverage: CoverageMetrics | None + """Coverage metrics.""" + + failed_jobs: BucketedFailures + """Bucketed failed job overview.""" + + passed: int + """Number of tests passed.""" + total: int + """Total number of tests run.""" + percent: float + """Percentage test pass rate.""" + + @staticmethod + def load(path: Path) -> "FlowResults": + """Load results from JSON file. + + Transform the fields of the loaded JSON into a more useful schema for + report generation. + + Args: + path: to the json file to load. + + """ + return FlowResults.model_validate_json(path.read_text()) + + +class SimResultsSummary(BaseModel): + """Summary of results.""" + + model_config = ConfigDict(frozen=True, extra="forbid") + + top: IPMeta + """Meta data for the top level config.""" + + timestamp: datetime + """Run time stamp.""" + + flow_results: Mapping[str, SimFlowResults] + """Flow results.""" + + report_path: Path + """Path to the report JSON file.""" + + @staticmethod + def load(path: Path) -> "SimResultsSummary": + """Load results from JSON file. + + Transform the fields of the loaded JSON into a more useful schema for + report generation. + + Args: + path: to the json file to load. + + Returns: + The loaded ResultsSummary from JSON. + + """ + return SimResultsSummary.model_validate_json(path.read_text()) diff --git a/src/dvsim/flow/sim.py b/src/dvsim/sim/flow.py similarity index 90% rename from src/dvsim/flow/sim.py rename to src/dvsim/sim/flow.py index 5dde9a3..d9e3f86 100644 --- a/src/dvsim/flow/sim.py +++ b/src/dvsim/sim/flow.py @@ -7,7 +7,7 @@ import fnmatch import sys from collections import OrderedDict, defaultdict -from collections.abc import Sequence +from collections.abc import Mapping, Sequence from datetime import datetime, timezone from pathlib import Path from typing import ClassVar @@ -25,12 +25,24 @@ from dvsim.logging import log from dvsim.modes import BuildMode, Mode, RunMode, find_mode from dvsim.regression import Regression -from dvsim.report.data import FlowResults, IPMeta, Testpoint, TestResult, TestStage, ToolMeta +from dvsim.sim.data import ( + IPMeta, + SimFlowResults, + SimResultsSummary, + Testpoint, + TestResult, + TestStage, + ToolMeta, +) +from dvsim.sim.report import gen_block_report, gen_reports from dvsim.sim_results import BucketedFailures, SimResults from dvsim.test import Test from dvsim.testplan import Testplan from dvsim.tool.utils import get_sim_tool_plugin from dvsim.utils import TS_FORMAT, rm_path +from dvsim.utils.git import git_commit_hash + +__all__ = ("SimCfg",) # This affects the bucketizer failure report. _MAX_UNIQUE_TESTS = 5 @@ -574,13 +586,83 @@ def cov_unr(self) -> None: for item in self.cfgs: item._cov_unr() + def gen_results(self, results: Sequence[CompletedJobStatus]) -> None: + """Generate flow results. + + Args: + results: completed job status objects. + + """ + reports_dir = Path(self.scratch_base_path) / "reports" + commit = git_commit_hash(path=Path(self.proj_root)) + url = f"https://github.com/lowrisc/opentitan/tree/{commit}" + + all_flow_results: Mapping[str, SimFlowResults] = {} + + for item in self.cfgs: + item_results = [ + res + for res in results + if res.block.name == item.name and res.block.variant == item.variant + ] + + flow_results: SimFlowResults = item._gen_json_results( + run_results=item_results, + commit=commit, + url=url, + ) + + # Convert to lowercase to match filename + block_result_index = ( + f"{item.name}_{item.variant}" if item.variant else item.name + ).lower() + + all_flow_results[block_result_index] = flow_results + + # Generate the block's JSON/HTML reports to the report area. + gen_block_report( + results=flow_results, + path=reports_dir, + ) + + self.errors_seen |= item.errors_seen + + if self.is_primary_cfg: + # The timestamp for this run has been taken with `utcnow()` and is + # stored in a custom format. Store it in standard ISO format with + # explicit timezone annotation. + timestamp = ( + datetime.strptime(self.timestamp, "%Y%m%d_%H%M%S") + .replace(tzinfo=timezone.utc) + .isoformat() + ) + + results_summary = SimResultsSummary( + top=IPMeta( + name=self.name, + variant=self.variant, + commit=commit, + branch=self.branch, + url=url, + ), + timestamp=timestamp, + flow_results=all_flow_results, + report_path=reports_dir, + ) + + # Generate all the JSON/HTML reports to the report area. + gen_reports( + summary=results_summary, + path=reports_dir, + ) + def _gen_json_results( self, run_results: Sequence[CompletedJobStatus], commit: str, url: str, - ) -> FlowResults: - """Generate structured FlowResults from simulation run data. + ) -> SimFlowResults: + """Generate structured SimFlowResults from simulation run data. Args: run_results: completed job status. @@ -700,7 +782,7 @@ def make_test_result(tr) -> TestResult | None: failures = BucketedFailures.from_job_status(results=run_results) # --- Final result --- - return FlowResults( + return SimFlowResults( block=block, tool=tool, timestamp=timestamp, diff --git a/src/dvsim/report/generate.py b/src/dvsim/sim/report.py similarity index 89% rename from src/dvsim/report/generate.py rename to src/dvsim/sim/report.py index fca0794..435f74d 100644 --- a/src/dvsim/report/generate.py +++ b/src/dvsim/sim/report.py @@ -7,7 +7,7 @@ from pathlib import Path from dvsim.logging import log -from dvsim.report.data import FlowResults, ResultsSummary +from dvsim.sim.data import SimFlowResults, SimResultsSummary from dvsim.templates.render import render_static, render_template __all__ = ( @@ -17,7 +17,7 @@ ) -def gen_block_report(results: FlowResults, path: Path) -> None: +def gen_block_report(results: SimFlowResults, path: Path) -> None: """Generate a block report. Args: @@ -47,7 +47,7 @@ def gen_block_report(results: FlowResults, path: Path) -> None: ) -def gen_summary_report(summary: ResultsSummary, path: Path) -> None: +def gen_summary_report(summary: SimResultsSummary, path: Path) -> None: """Generate a summary report. Args: @@ -88,7 +88,7 @@ def gen_summary_report(summary: ResultsSummary, path: Path) -> None: ) -def gen_reports(summary: ResultsSummary, path: Path) -> None: +def gen_reports(summary: SimResultsSummary, path: Path) -> None: """Generate a full set of reports for the given regression run. Args: diff --git a/src/dvsim/sim/tool/__init__.py b/src/dvsim/sim/tool/__init__.py new file mode 100644 index 0000000..f5f58ab --- /dev/null +++ b/src/dvsim/sim/tool/__init__.py @@ -0,0 +1,5 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +"""Simulation Tools.""" diff --git a/src/dvsim/tool/sim.py b/src/dvsim/sim/tool/base.py similarity index 98% rename from src/dvsim/tool/sim.py rename to src/dvsim/sim/tool/base.py index 2807dbb..896ac20 100644 --- a/src/dvsim/tool/sim.py +++ b/src/dvsim/sim/tool/base.py @@ -8,7 +8,7 @@ from pathlib import Path from typing import Protocol, runtime_checkable -from dvsim.report.data import CoverageMetrics +from dvsim.sim.data import CoverageMetrics __all__ = ("SimTool",) diff --git a/src/dvsim/tool/vcs.py b/src/dvsim/sim/tool/vcs.py similarity index 98% rename from src/dvsim/tool/vcs.py rename to src/dvsim/sim/tool/vcs.py index b40cc6e..4948416 100644 --- a/src/dvsim/tool/vcs.py +++ b/src/dvsim/sim/tool/vcs.py @@ -8,7 +8,7 @@ from collections.abc import Mapping, Sequence from pathlib import Path -from dvsim.report.data import CodeCoverageMetrics, CoverageMetrics +from dvsim.sim.data import CodeCoverageMetrics, CoverageMetrics __all__ = ("VCS",) diff --git a/src/dvsim/tool/xcelium.py b/src/dvsim/sim/tool/xcelium.py similarity index 98% rename from src/dvsim/tool/xcelium.py rename to src/dvsim/sim/tool/xcelium.py index b5e62ad..0362f48 100644 --- a/src/dvsim/tool/xcelium.py +++ b/src/dvsim/sim/tool/xcelium.py @@ -9,7 +9,7 @@ from collections.abc import Mapping, Sequence from pathlib import Path -from dvsim.report.data import CodeCoverageMetrics, CoverageMetrics +from dvsim.sim.data import CodeCoverageMetrics, CoverageMetrics __all__ = ("Xcelium",) diff --git a/src/dvsim/tool/utils.py b/src/dvsim/tool/utils.py index 0997f85..eeb3b55 100644 --- a/src/dvsim/tool/utils.py +++ b/src/dvsim/tool/utils.py @@ -5,9 +5,9 @@ """EDA Tool base.""" from dvsim.logging import log -from dvsim.tool.sim import SimTool -from dvsim.tool.vcs import VCS -from dvsim.tool.xcelium import Xcelium +from dvsim.sim.tool.base import SimTool +from dvsim.sim.tool.vcs import VCS +from dvsim.sim.tool.xcelium import Xcelium __all__ = ("get_sim_tool_plugin",) diff --git a/tests/tool/test_utils.py b/tests/tool/test_utils.py index 8389eb5..28c211d 100644 --- a/tests/tool/test_utils.py +++ b/tests/tool/test_utils.py @@ -7,7 +7,7 @@ import pytest from hamcrest import assert_that, equal_to, instance_of -from dvsim.tool.sim import SimTool +from dvsim.sim.tool.base import SimTool from dvsim.tool.utils import _SUPPORTED_SIM_TOOLS, get_sim_tool_plugin __all__ = ("TestEDAToolPlugins",)