|
1 | | -import os |
| 1 | +import inspect |
2 | 2 | import importlib.resources |
3 | 3 | import logging |
| 4 | +import os |
| 5 | +import subprocess |
4 | 6 |
|
5 | 7 | from contextlib import contextmanager |
6 | 8 | from pathlib import Path |
|
12 | 14 | from amaranth import Module |
13 | 15 |
|
14 | 16 | from . import StepBase, _wire_up_ports |
| 17 | +from ._json_compare import compare_events |
15 | 18 | from .. import ChipFlowError, _ensure_chipflow_root |
16 | | -from ..platforms._utils import top_components |
| 19 | +from ..cli import run |
| 20 | +from ..platforms._utils import top_components, load_pinlock |
17 | 21 | from ..platforms.sim import VARIABLES, TASKS, DOIT_CONFIG, SimPlatform |
18 | 22 |
|
19 | 23 |
|
@@ -75,7 +79,34 @@ def __init__(self, config): |
75 | 79 | self._platform = SimPlatform(config) |
76 | 80 | self._config = config |
77 | 81 |
|
| 82 | + def build_cli_parser(self, parser): |
| 83 | + action_argument = parser.add_subparsers(dest="action") |
| 84 | + action_argument.add_parser( |
| 85 | + "build", help=inspect.getdoc(self.build).splitlines()[0]) # type: ignore |
| 86 | + action_argument.add_parser( |
| 87 | + "run", help=inspect.getdoc(self.run).splitlines()[0]) # type: ignore |
| 88 | + action_argument.add_parser( |
| 89 | + "check", help=inspect.getdoc(self.check).splitlines()[0]) # type: ignore |
| 90 | + |
| 91 | + def run_cli(self, args): |
| 92 | + load_pinlock() # check pinlock first so we error cleanly |
| 93 | + |
| 94 | + match (args.action): |
| 95 | + case "build": |
| 96 | + self.build(args) |
| 97 | + case "run": |
| 98 | + self.run(args) |
| 99 | + case "check": |
| 100 | + self.check(args) |
| 101 | + |
| 102 | + @property |
| 103 | + def sim_dir(self): |
| 104 | + return _ensure_chipflow_root() / 'build' / 'sim' |
| 105 | + |
78 | 106 | def build(self, *args): |
| 107 | + """ |
| 108 | + Builds the simulation model for the design |
| 109 | + """ |
79 | 110 | print("Building simulation...") |
80 | 111 | m = Module() |
81 | 112 | self._platform.instantiate_ports(m) |
@@ -107,3 +138,28 @@ def build(self, *args): |
107 | 138 | context[k] = v.format(**context) |
108 | 139 | if DoitMain(ContextTaskLoader(DOIT_CONFIG, TASKS, context)).run(["build_sim"]) !=0: |
109 | 140 | raise ChipFlowError("Failed building simulator") |
| 141 | + |
| 142 | + def run(self, *args): |
| 143 | + """ |
| 144 | + Run the simulation. Will ensure that the simulation and the software are both built. |
| 145 | + """ |
| 146 | + run(["software"]) |
| 147 | + self.build(args) |
| 148 | + result = subprocess.run([self.sim_dir / "sim_soc"], cwd=self.sim_dir) |
| 149 | + |
| 150 | + if result.returncode != 0: |
| 151 | + raise ChipFlowError("Simulation failed") |
| 152 | + |
| 153 | + def check(self, *args): |
| 154 | + """ |
| 155 | + Run the simulation and check events against reference (tests/events_reference.json). Will ensure that the simulation and the software are both built. |
| 156 | + """ |
| 157 | + if not self._config.chipflow.test: |
| 158 | + raise ChipFlowError("No [chipflow.test] section found in configuration") |
| 159 | + if not self._config.chipflow.test.event_reference: |
| 160 | + raise ChipFlowError("No event_reference configuration found in [chipflow.test]") |
| 161 | + |
| 162 | + self.run(args) |
| 163 | + compare_events(self._config.chipflow.test.event_reference, self.sim_dir / "events.json") |
| 164 | + print("Integration test passed sucessfully") |
| 165 | + |
0 commit comments