dvsim 1.7.1__tar.gz → 1.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. {dvsim-1.7.1 → dvsim-1.7.3}/CHANGELOG.md +24 -0
  2. {dvsim-1.7.1 → dvsim-1.7.3}/PKG-INFO +1 -1
  3. {dvsim-1.7.1 → dvsim-1.7.3}/pyproject.toml +1 -1
  4. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/cli/admin.py +3 -3
  5. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/base.py +1 -66
  6. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/factory.py +1 -1
  7. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/formal.py +46 -38
  8. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/lint.py +26 -21
  9. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/one_shot.py +55 -6
  10. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/job/deploy.py +4 -0
  11. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/base.py +18 -15
  12. dvsim-1.7.3/src/dvsim/report/data.py +41 -0
  13. dvsim-1.7.3/src/dvsim/sim/__init__.py +5 -0
  14. {dvsim-1.7.1/src/dvsim/report → dvsim-1.7.3/src/dvsim/sim}/data.py +54 -36
  15. dvsim-1.7.1/src/dvsim/flow/sim.py → dvsim-1.7.3/src/dvsim/sim/flow.py +87 -5
  16. dvsim-1.7.1/src/dvsim/report/generate.py → dvsim-1.7.3/src/dvsim/sim/report.py +4 -4
  17. dvsim-1.7.3/src/dvsim/sim/tool/__init__.py +5 -0
  18. dvsim-1.7.1/src/dvsim/tool/sim.py → dvsim-1.7.3/src/dvsim/sim/tool/base.py +1 -1
  19. {dvsim-1.7.1/src/dvsim → dvsim-1.7.3/src/dvsim/sim}/tool/vcs.py +1 -1
  20. {dvsim-1.7.1/src/dvsim → dvsim-1.7.3/src/dvsim/sim}/tool/xcelium.py +1 -1
  21. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/tool/utils.py +3 -3
  22. {dvsim-1.7.1 → dvsim-1.7.3}/tests/tool/test_utils.py +1 -1
  23. {dvsim-1.7.1 → dvsim-1.7.3}/uv.lock +1 -1
  24. {dvsim-1.7.1 → dvsim-1.7.3}/.envrc +0 -0
  25. {dvsim-1.7.1 → dvsim-1.7.3}/.github/actions/lowrisc_ci_app_get_token/action.yml +0 -0
  26. {dvsim-1.7.1 → dvsim-1.7.3}/.github/workflows/ci.yml +0 -0
  27. {dvsim-1.7.1 → dvsim-1.7.3}/.github/workflows/release.yml +0 -0
  28. {dvsim-1.7.1 → dvsim-1.7.3}/.gitignore +0 -0
  29. {dvsim-1.7.1 → dvsim-1.7.3}/.python-version +0 -0
  30. {dvsim-1.7.1 → dvsim-1.7.3}/CLA +0 -0
  31. {dvsim-1.7.1 → dvsim-1.7.3}/CONTRIBUTING.md +0 -0
  32. {dvsim-1.7.1 → dvsim-1.7.3}/LICENSE +0 -0
  33. {dvsim-1.7.1 → dvsim-1.7.3}/NOTICE +0 -0
  34. {dvsim-1.7.1 → dvsim-1.7.3}/README.md +0 -0
  35. {dvsim-1.7.1 → dvsim-1.7.3}/SECURITY.md +0 -0
  36. {dvsim-1.7.1 → dvsim-1.7.3}/doc/architecture.png +0 -0
  37. {dvsim-1.7.1 → dvsim-1.7.3}/doc/design_doc.md +0 -0
  38. {dvsim-1.7.1 → dvsim-1.7.3}/doc/glossary.md +0 -0
  39. {dvsim-1.7.1 → dvsim-1.7.3}/doc/opentitan-logo.png +0 -0
  40. {dvsim-1.7.1 → dvsim-1.7.3}/doc/testplanner.md +0 -0
  41. {dvsim-1.7.1 → dvsim-1.7.3}/flake.lock +0 -0
  42. {dvsim-1.7.1 → dvsim-1.7.3}/flake.nix +0 -0
  43. {dvsim-1.7.1 → dvsim-1.7.3}/ruff-ci.toml +0 -0
  44. {dvsim-1.7.1 → dvsim-1.7.3}/scripts/license_check.py +0 -0
  45. {dvsim-1.7.1 → dvsim-1.7.3}/scripts/lint_commits.py +0 -0
  46. {dvsim-1.7.1 → dvsim-1.7.3}/scripts/update_js.sh +0 -0
  47. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/__init__.py +0 -0
  48. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/cli/__init__.py +0 -0
  49. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/cli/run.py +0 -0
  50. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/examples/testplanner/common_testplan.hjson +0 -0
  51. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/examples/testplanner/foo_dv_doc.md +0 -0
  52. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/examples/testplanner/foo_sim_results.hjson +0 -0
  53. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/examples/testplanner/foo_testplan.hjson +0 -0
  54. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/__init__.py +0 -0
  55. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/cdc.py +0 -0
  56. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/hjson.py +0 -0
  57. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/rdc.py +0 -0
  58. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/flow/syn.py +0 -0
  59. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/job/__init__.py +0 -0
  60. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/job/data.py +0 -0
  61. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/job/time.py +0 -0
  62. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/__init__.py +0 -0
  63. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/factory.py +0 -0
  64. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/fake.py +0 -0
  65. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/local.py +0 -0
  66. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/lsf.py +0 -0
  67. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/nc.py +0 -0
  68. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/sge/__init__.py +0 -0
  69. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/sge/engine.py +0 -0
  70. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/sge/launcher.py +0 -0
  71. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/sge/qsubopts.py +0 -0
  72. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/launcher/slurm.py +0 -0
  73. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/linting/__init__.py +0 -0
  74. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/linting/parser.py +0 -0
  75. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/logging.py +0 -0
  76. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/modes.py +0 -0
  77. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/msg_bucket.py +0 -0
  78. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/msg_buckets.py +0 -0
  79. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/regression.py +0 -0
  80. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/report/__init__.py +0 -0
  81. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/scheduler.py +0 -0
  82. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/sim_results.py +0 -0
  83. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/__init__.py +0 -0
  84. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/render.py +0 -0
  85. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/reports/__init__.py +0 -0
  86. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/reports/block_report.html +0 -0
  87. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/reports/redirect.html +0 -0
  88. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/reports/summary_report.html +0 -0
  89. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/reports/wrapper.html +0 -0
  90. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/static/css/bootstrap.min.css +0 -0
  91. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/static/css/style.css +0 -0
  92. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/static/js/bootstrap.bundle.min.js +0 -0
  93. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/templates/static/js/htmx.min.js +0 -0
  94. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/test.py +0 -0
  95. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/testplan.py +0 -0
  96. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/testplanner.py +0 -0
  97. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/tool/__init__.py +0 -0
  98. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/tool/ascentlint.py +0 -0
  99. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/tool/meridianrdc.py +0 -0
  100. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/tool/verilator.py +0 -0
  101. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/__init__.py +0 -0
  102. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/check.py +0 -0
  103. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/fs.py +0 -0
  104. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/git.py +0 -0
  105. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/hjson.py +0 -0
  106. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/json.py +0 -0
  107. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/status_printer.py +0 -0
  108. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/subprocess.py +0 -0
  109. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/timer.py +0 -0
  110. {dvsim-1.7.1 → dvsim-1.7.3}/src/dvsim/utils/wildcards.py +0 -0
  111. {dvsim-1.7.1 → dvsim-1.7.3}/tests/__init__.py +0 -0
  112. {dvsim-1.7.1 → dvsim-1.7.3}/tests/job/__init__.py +0 -0
  113. {dvsim-1.7.1 → dvsim-1.7.3}/tests/job/test_deploy.py +0 -0
  114. {dvsim-1.7.1 → dvsim-1.7.3}/tests/job/test_time.py +0 -0
  115. {dvsim-1.7.1 → dvsim-1.7.3}/tests/templates/__init__.py +0 -0
  116. {dvsim-1.7.1 → dvsim-1.7.3}/tests/templates/test_render.py +0 -0
  117. {dvsim-1.7.1 → dvsim-1.7.3}/tests/test_cli.py +0 -0
  118. {dvsim-1.7.1 → dvsim-1.7.3}/tests/tool/__init__.py +0 -0
  119. {dvsim-1.7.1 → dvsim-1.7.3}/tests/tool/test_vcs.py +0 -0
  120. {dvsim-1.7.1 → dvsim-1.7.3}/tests/utils/__init__.py +0 -0
  121. {dvsim-1.7.1 → dvsim-1.7.3}/tests/utils/test_fs.py +0 -0
  122. {dvsim-1.7.1 → dvsim-1.7.3}/tests/utils/test_git.py +0 -0
  123. {dvsim-1.7.1 → dvsim-1.7.3}/tests/utils/test_wildcards.py +0 -0
@@ -2,6 +2,30 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v1.7.3 (2026-01-21)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Formal flow
10
+ ([`bd28563`](https://github.com/lowRISC/dvsim/commit/bd2856360b8ca5355e860f7fb9c3d3888d4663e8))
11
+
12
+
13
+ ## v1.7.2 (2026-01-21)
14
+
15
+ ### Bug Fixes
16
+
17
+ - Hacky workaround for sim centric code
18
+ ([`596d92f`](https://github.com/lowRISC/dvsim/commit/596d92fa4b0e69bf69b3b23e086db0ba72e3d0aa))
19
+
20
+ - Restore the lint flow old style report
21
+ ([`85d8550`](https://github.com/lowRISC/dvsim/commit/85d8550db2fb4f3404ac6c96dc8baf64e8fd44bb))
22
+
23
+ ### Refactoring
24
+
25
+ - Move sim related modules to top level package
26
+ ([`9e31623`](https://github.com/lowRISC/dvsim/commit/9e31623a722e3ef4e500dc83072c49f5da803fd0))
27
+
28
+
5
29
  ## v1.7.1 (2026-01-08)
6
30
 
7
31
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dvsim
3
- Version: 1.7.1
3
+ Version: 1.7.3
4
4
  Summary: DV system
5
5
  Author: lowRISC contributors (OpenTitan project)
6
6
  License-File: LICENSE
@@ -8,7 +8,7 @@
8
8
 
9
9
  [project]
10
10
  name = "dvsim"
11
- version = "1.7.1"
11
+ version = "1.7.3"
12
12
  description = "DV system"
13
13
  authors = [{name = "lowRISC contributors (OpenTitan project)"}]
14
14
  readme = "README.md"
@@ -35,9 +35,9 @@ def report() -> None:
35
35
  )
36
36
  def gen(json_path: Path, output_dir: Path) -> None:
37
37
  """Generate a report from a existing results JSON."""
38
- from dvsim.report.data import ResultsSummary
39
- from dvsim.report.generate import gen_reports
38
+ from dvsim.sim.data import SimResultsSummary
39
+ from dvsim.sim.report import gen_reports
40
40
 
41
- results: ResultsSummary = ResultsSummary.load(path=json_path)
41
+ results: SimResultsSummary = SimResultsSummary.load(path=json_path)
42
42
 
43
43
  gen_reports(summary=results, path=output_dir)
@@ -10,7 +10,6 @@ import pprint
10
10
  import sys
11
11
  from abc import ABC, abstractmethod
12
12
  from collections.abc import Mapping, Sequence
13
- from datetime import datetime, timezone
14
13
  from pathlib import Path
15
14
  from typing import TYPE_CHECKING, ClassVar
16
15
 
@@ -20,15 +19,12 @@ from dvsim.flow.hjson import set_target_attribute
20
19
  from dvsim.job.data import CompletedJobStatus
21
20
  from dvsim.launcher.factory import get_launcher_cls
22
21
  from dvsim.logging import log
23
- from dvsim.report.data import FlowResults, IPMeta, ResultsSummary
24
- from dvsim.report.generate import gen_block_report, gen_reports
25
22
  from dvsim.scheduler import Scheduler
26
23
  from dvsim.utils import (
27
24
  find_and_substitute_wildcards,
28
25
  rm_path,
29
26
  subst_wildcards,
30
27
  )
31
- from dvsim.utils.git import git_commit_hash
32
28
 
33
29
  if TYPE_CHECKING:
34
30
  from dvsim.job.deploy import Deploy
@@ -447,6 +443,7 @@ class FlowCfg(ABC):
447
443
  interactive=self.interactive,
448
444
  ).run()
449
445
 
446
+ @abstractmethod
450
447
  def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
451
448
  """Generate flow results.
452
449
 
@@ -454,68 +451,6 @@ class FlowCfg(ABC):
454
451
  results: completed job status objects.
455
452
 
456
453
  """
457
- reports_dir = Path(self.scratch_base_path) / "reports"
458
- commit = git_commit_hash(path=Path(self.proj_root))
459
- url = f"https://github.com/lowrisc/opentitan/tree/{commit}"
460
-
461
- all_flow_results: Mapping[str, FlowResults] = {}
462
-
463
- for item in self.cfgs:
464
- item_results = [
465
- res
466
- for res in results
467
- if res.block.name == item.name and res.block.variant == item.variant
468
- ]
469
-
470
- flow_results: FlowResults = item._gen_json_results(
471
- run_results=item_results,
472
- commit=commit,
473
- url=url,
474
- )
475
-
476
- # Convert to lowercase to match filename
477
- block_result_index = (
478
- f"{item.name}_{item.variant}" if item.variant else item.name
479
- ).lower()
480
-
481
- all_flow_results[block_result_index] = flow_results
482
-
483
- # Generate the block's JSON/HTML reports to the report area.
484
- gen_block_report(
485
- results=flow_results,
486
- path=reports_dir,
487
- )
488
-
489
- self.errors_seen |= item.errors_seen
490
-
491
- if self.is_primary_cfg:
492
- # The timestamp for this run has been taken with `utcnow()` and is
493
- # stored in a custom format. Store it in standard ISO format with
494
- # explicit timezone annotation.
495
- timestamp = (
496
- datetime.strptime(self.timestamp, "%Y%m%d_%H%M%S")
497
- .replace(tzinfo=timezone.utc)
498
- .isoformat()
499
- )
500
-
501
- results_summary = ResultsSummary(
502
- top=IPMeta(
503
- name=self.name,
504
- variant=self.variant,
505
- commit=commit,
506
- branch=self.branch,
507
- url=url,
508
- ),
509
- timestamp=timestamp,
510
- flow_results=all_flow_results,
511
- report_path=reports_dir,
512
- )
513
-
514
- # Generate all the JSON/HTML reports to the report area.
515
- gen_reports(
516
- summary=results_summary,
517
- path=reports_dir,
518
- )
519
454
 
520
455
  def has_errors(self) -> bool:
521
456
  """Return error state."""
@@ -11,9 +11,9 @@ from dvsim.flow.formal import FormalCfg
11
11
  from dvsim.flow.hjson import load_hjson
12
12
  from dvsim.flow.lint import LintCfg
13
13
  from dvsim.flow.rdc import RdcCfg
14
- from dvsim.flow.sim import SimCfg
15
14
  from dvsim.flow.syn import SynCfg
16
15
  from dvsim.logging import log
16
+ from dvsim.sim.flow import SimCfg
17
17
 
18
18
  FLOW_HANDLERS = {
19
19
  "cdc": CdcCfg,
@@ -2,12 +2,14 @@
2
2
  # Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ from collections.abc import Sequence
5
6
  from pathlib import Path
6
7
 
7
8
  import hjson
8
9
  from tabulate import tabulate
9
10
 
10
11
  from dvsim.flow.one_shot import OneShotCfg
12
+ from dvsim.job.data import CompletedJobStatus
11
13
  from dvsim.logging import log
12
14
  from dvsim.utils import subst_wildcards
13
15
 
@@ -176,41 +178,47 @@ class FormalCfg(OneShotCfg):
176
178
 
177
179
  return self.results_summary_md
178
180
 
179
- def _gen_results(self, results):
180
- # This function is called after the regression and looks for
181
- # results.hjson file with aggregated results from the formal logfile.
182
- # The hjson file is required to follow this format:
183
- # {
184
- # "messages": {
185
- # "errors" : []
186
- # "warnings" : []
187
- # "cex" : ["property1", "property2"...],
188
- # "undetermined": [],
189
- # "unreachable" : [],
190
- # },
191
- #
192
- # "summary": {
193
- # "errors" : 0
194
- # "warnings" : 2
195
- # "proven" : 20,
196
- # "cex" : 5,
197
- # "covered" : 18,
198
- # "undetermined": 7,
199
- # "unreachable" : 2,
200
- # "pass_rate" : "90 %",
201
- # "cover_rate" : "90 %"
202
- # },
203
- # }
204
- # The categories for property results are: proven, cex, undetermined,
205
- # covered, and unreachable.
206
- #
207
- # If coverage was enabled then results.hjson will also have an item that
208
- # shows formal coverage. It will have the following format:
209
- # "coverage": {
210
- # formal: "90 %",
211
- # stimuli: "90 %",
212
- # checker: "80 %"
213
- # }
181
+ def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
182
+ """Generate results.
183
+
184
+ This function is called after the regression and looks for
185
+ results.hjson file with aggregated results from the formal logfile.
186
+ The hjson file is required to follow this format:
187
+ {
188
+ "messages": {
189
+ "errors" : []
190
+ "warnings" : []
191
+ "cex" : ["property1", "property2"...],
192
+ "undetermined": [],
193
+ "unreachable" : [],
194
+ },
195
+
196
+ "summary": {
197
+ "errors" : 0
198
+ "warnings" : 2
199
+ "proven" : 20,
200
+ "cex" : 5,
201
+ "covered" : 18,
202
+ "undetermined": 7,
203
+ "unreachable" : 2,
204
+ "pass_rate" : "90 %",
205
+ "cover_rate" : "90 %"
206
+ },
207
+ }
208
+ The categories for property results are: proven, cex, undetermined,
209
+ covered, and unreachable.
210
+
211
+ If coverage was enabled then results.hjson will also have an item that
212
+ shows formal coverage. It will have the following format:
213
+ "coverage": {
214
+ formal: "90 %",
215
+ stimuli: "90 %",
216
+ checker: "80 %"
217
+ }
218
+ """
219
+ # There should be just one job that has run for this config.
220
+ complete_job = results[0]
221
+
214
222
  results_str = "## " + self.results_title + "\n\n"
215
223
  results_str += "### " + self.timestamp_long + "\n"
216
224
  if self.revision:
@@ -222,7 +230,7 @@ class FormalCfg(OneShotCfg):
222
230
  assert len(self.deploy) == 1
223
231
  mode = self.deploy[0]
224
232
 
225
- if results[mode] == "P":
233
+ if complete_job.status == "P":
226
234
  result_data = Path(
227
235
  subst_wildcards(self.build_dir, {"build_mode": mode.name}),
228
236
  "results.hjson",
@@ -254,8 +262,8 @@ class FormalCfg(OneShotCfg):
254
262
  else:
255
263
  summary += ["N/A", "N/A", "N/A"]
256
264
 
257
- if results[mode] != "P":
258
- results_str += "\n## List of Failures\n" + "".join(mode.launcher.fail_msg.message)
265
+ if complete_job.status != "P":
266
+ results_str += "\n## List of Failures\n" + "".join(complete_job.fail_msg.message)
259
267
 
260
268
  messages = self.result.get("messages")
261
269
  if messages is not None:
@@ -4,11 +4,13 @@
4
4
 
5
5
  """Class describing lint configuration object."""
6
6
 
7
+ from collections.abc import Sequence
7
8
  from pathlib import Path
8
9
 
9
10
  from tabulate import tabulate
10
11
 
11
12
  from dvsim.flow.one_shot import OneShotCfg
13
+ from dvsim.job.data import CompletedJobStatus
12
14
  from dvsim.logging import log
13
15
  from dvsim.msg_buckets import MsgBuckets
14
16
  from dvsim.utils import check_bool, subst_wildcards
@@ -76,7 +78,10 @@ class LintCfg(OneShotCfg):
76
78
 
77
79
  keys = self.totals.get_keys(self.report_severities)
78
80
  for cfg in self.cfgs:
79
- name_with_link = cfg._get_results_page_link(self.results_dir)
81
+ link_text = self.name.upper()
82
+ relative_link = Path(self.results_dir) / self.results_page
83
+
84
+ name_with_link = f"[{link_text}]({relative_link})"
80
85
 
81
86
  row = [name_with_link]
82
87
  row += cfg.result_summary.get_counts_md(keys)
@@ -96,26 +101,26 @@ class LintCfg(OneShotCfg):
96
101
 
97
102
  # TODO(#9079): This way of parsing out messages into an intermediate
98
103
  # results.hjson file will be replaced by a native parser mechanism.
99
- def _gen_results(self, results):
100
- # '''
101
- # The function is called after the regression has completed. It looks
102
- # for a results.hjson file with aggregated results from the lint run.
103
- # The hjson needs to have the following format:
104
- #
105
- # {
106
- # bucket_key: [str],
107
- # // other buckets according to message_buckets configuration
108
- # }
109
- #
110
- # Each bucket key points to a list of signatures (strings).
111
- # The bucket categories and severities are defined in the
112
- # message_buckets class variable, and can be set via Hjson Dvsim
113
- # config files.
114
- #
115
- # Note that if this is a primary config, the results will
116
- # be generated using the _gen_results_summary function
117
- # '''
118
-
104
+ def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
105
+ """Generate results.
106
+
107
+ The function is called after the regression has completed. It looks
108
+ for a results.hjson file with aggregated results from the lint run.
109
+ The hjson needs to have the following format:
110
+
111
+ {
112
+ bucket_key: [str],
113
+ // other buckets according to message_buckets configuration
114
+ }
115
+
116
+ Each bucket key points to a list of signatures (strings).
117
+ The bucket categories and severities are defined in the
118
+ message_buckets class variable, and can be set via Hjson Dvsim
119
+ config files.
120
+
121
+ Note that if this is a primary config, the results will
122
+ be generated using the _gen_results_summary function
123
+ """
119
124
  # Generate results table for runs.
120
125
  results_str = f"## {self.results_title}\n\n"
121
126
  results_str += f"### {self.timestamp_long}\n"
@@ -4,10 +4,13 @@
4
4
 
5
5
  """Class describing a one-shot build configuration object."""
6
6
 
7
- import pathlib
7
+ from abc import abstractmethod
8
8
  from collections import OrderedDict
9
+ from collections.abc import Sequence
10
+ from pathlib import Path
9
11
 
10
12
  from dvsim.flow.base import FlowCfg
13
+ from dvsim.job.data import CompletedJobStatus
11
14
  from dvsim.job.deploy import CompileOneShot
12
15
  from dvsim.logging import log
13
16
  from dvsim.modes import BuildMode, Mode
@@ -15,9 +18,7 @@ from dvsim.utils import rm_path
15
18
 
16
19
 
17
20
  class OneShotCfg(FlowCfg):
18
- """Simple one-shot build flow for non-simulation targets like
19
- linting, synthesis and FPV.
20
- """
21
+ """Simple one-shot build flow for non-simulation targets like linting, synthesis and FPV."""
21
22
 
22
23
  ignored_wildcards = [*FlowCfg.ignored_wildcards, "build_mode", "index", "test"]
23
24
 
@@ -134,8 +135,10 @@ class OneShotCfg(FlowCfg):
134
135
  def _create_dirs(self) -> None:
135
136
  """Create initial set of directories."""
136
137
  for link in self.links:
137
- rm_path(self.links[link])
138
- pathlib.Path(self.links[link]).mkdir(parents=True)
138
+ link_path = Path(self.links[link])
139
+
140
+ rm_path(link_path)
141
+ link_path.mkdir(parents=True)
139
142
 
140
143
  def _create_deploy_objects(self) -> None:
141
144
  """Create deploy objects from build modes."""
@@ -149,3 +152,49 @@ class OneShotCfg(FlowCfg):
149
152
 
150
153
  # Create initial set of directories before kicking off the regression.
151
154
  self._create_dirs()
155
+
156
+ @abstractmethod
157
+ def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
158
+ """Generate results for this config."""
159
+
160
+ @abstractmethod
161
+ def gen_results_summary(self):
162
+ """Gathers the aggregated results from all sub configs."""
163
+
164
+ def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
165
+ """Generate flow results.
166
+
167
+ Args:
168
+ results: completed job status objects.
169
+
170
+ """
171
+ for item in self.cfgs:
172
+ project = item.name
173
+
174
+ item_results = [
175
+ res
176
+ for res in results
177
+ if res.block.name == item.name and res.block.variant == item.variant
178
+ ]
179
+
180
+ result = item._gen_results(item_results)
181
+
182
+ log.info("[results]: [%s]:\n%s\n", project, result)
183
+ log.info("[scratch_path]: [%s] [%s]", project, item.scratch_path)
184
+
185
+ # TODO: Implement HTML report using templates
186
+
187
+ results_dir = Path(self.results_dir)
188
+ results_dir.mkdir(exist_ok=True, parents=True)
189
+
190
+ # (results_dir / self.results_html_name).write_text(
191
+ # md_results_to_html(self.results_title, self.css_file, item.results_md)
192
+ # )
193
+
194
+ log.verbose("[report]: [%s] [%s/report.html]", project, item.results_dir)
195
+
196
+ self.errors_seen |= item.errors_seen
197
+
198
+ if self.is_primary_cfg:
199
+ self.gen_results_summary()
200
+ # self.write_results(self.results_html_name, self.results_summary_md)
@@ -74,6 +74,10 @@ class Deploy:
74
74
  # Cross ref the whole cfg object for ease.
75
75
  self.sim_cfg = sim_cfg
76
76
  self.flow = sim_cfg.name
77
+
78
+ if not hasattr(self.sim_cfg, "variant"):
79
+ self.sim_cfg.variant = ""
80
+
77
81
  self._variant_suffix = f"_{self.sim_cfg.variant}" if self.sim_cfg.variant else ""
78
82
 
79
83
  # A list of jobs on which this job depends.
@@ -339,25 +339,28 @@ class Launcher(ABC):
339
339
  # since it is devoid of the delays incurred due to infrastructure and
340
340
  # setup overhead.
341
341
 
342
- plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name)
342
+ time = self.job_runtime_secs
343
+ unit = "s"
344
+
345
+ if self.job_spec.job_type in [
346
+ "CompileSim",
347
+ "RunTest",
348
+ "CovUnr",
349
+ "CovMerge",
350
+ "CovReport",
351
+ "CovAnalyze",
352
+ ]:
353
+ plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name)
343
354
 
344
- try:
345
- time, unit = plugin.get_job_runtime(log_text=lines)
346
- self.job_runtime.set(time, unit)
347
-
348
- except RuntimeError as e:
349
- log.warning(
350
- f"{self.job_spec.full_name}: {e} Using dvsim-maintained job_runtime instead."
351
- )
352
- self.job_runtime.set(self.job_runtime_secs, "s")
353
-
354
- if self.job_spec.job_type == "RunTest":
355
355
  try:
356
- time, unit = plugin.get_simulated_time(log_text=lines)
357
- self.simulated_time.set(time, unit)
356
+ time, unit = plugin.get_job_runtime(log_text=lines)
358
357
 
359
358
  except RuntimeError as e:
360
- log.debug(f"{self.job_spec.full_name}: {e}")
359
+ log.warning(
360
+ f"{self.job_spec.full_name}: {e} Using dvsim-maintained job_runtime instead."
361
+ )
362
+
363
+ self.job_runtime.set(time, unit)
361
364
 
362
365
  if chk_failed or chk_passed:
363
366
  for cnt, line in enumerate(lines):
@@ -0,0 +1,41 @@
1
+ # Copyright lowRISC contributors (OpenTitan project).
2
+ # Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """Report data models."""
6
+
7
+ from pydantic import BaseModel, ConfigDict
8
+
9
+ __all__ = (
10
+ "IPMeta",
11
+ "ToolMeta",
12
+ )
13
+
14
+
15
+ class IPMeta(BaseModel):
16
+ """Meta data for an IP block."""
17
+
18
+ model_config = ConfigDict(frozen=True, extra="forbid")
19
+
20
+ name: str
21
+ """Name of the IP."""
22
+ variant: str | None = None
23
+ """Variant of the IP if there is one."""
24
+
25
+ commit: str
26
+ """Git commit sha of the IP the tests are run against."""
27
+ branch: str
28
+ """Git branch"""
29
+ url: str
30
+ """URL to where the IP can be found in git (e.g. github)."""
31
+
32
+
33
+ class ToolMeta(BaseModel):
34
+ """Meta data for an EDA tool."""
35
+
36
+ model_config = ConfigDict(frozen=True, extra="forbid")
37
+
38
+ name: str
39
+ """Name of the tool."""
40
+ version: str
41
+ """Version of the tool."""
@@ -0,0 +1,5 @@
1
+ # Copyright lowRISC contributors (OpenTitan project).
2
+ # Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """Simulation workflow."""