Skip to content

Commit

Permalink
WIP fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kammoh committed Jul 17, 2024
1 parent c61b4fd commit c0808d7
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 132 deletions.
32 changes: 23 additions & 9 deletions src/xeda/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ def cli(ctx: click.Context, **kwargs):
default=True,
help="Incremental build. Useful during development. Flows run under a <design_name>/<flow_name>_<flow_settings_hash> subfolder in incremental mode.",
)
@click.option(
"--cwd",
is_flag=True,
help="Run incremental execution in the current working directory.",
)
@click.option(
"--clean",
is_flag=True,
Expand Down Expand Up @@ -265,13 +270,19 @@ def run(
post_cleanup_purge: bool = False,
scrub: bool = False,
remote: Optional[str] = None,
cwd: bool = False,
):
"""`run` command"""
assert ctx
options: XedaOptions = ctx.obj or XedaOptions()
assert xeda_run_dir
if not xeda_run_dir:
if cwd and remote:
log.critical("--cwd and --remote are mutually exclusive!")
sys.exit(1)
if cwd:
xeda_run_dir = Path.cwd()
elif xeda_run_dir is None:
xeda_run_dir = Path.cwd() / "xeda_run"

if log_level is None:
log_level = (
logging.DEBUG if options.debug else logging.WARNING if options.quiet else logging.INFO
Expand Down Expand Up @@ -304,11 +315,16 @@ def run(
xeda_run_dir,
cached_dependencies=cached_dependencies,
)
launcher.settings.incremental = incremental
launcher.settings.clean = clean
launcher.settings.post_cleanup = post_cleanup
launcher.settings.post_cleanup_purge = post_cleanup_purge
launcher.settings.scrub_old_runs = scrub
launcher.settings.cleanup_before_run = clean
if cwd:
launcher.settings.incremental = True
launcher.settings.run_path = Path.cwd()
launcher.settings.dump_results_json = False
else:
launcher.settings.incremental = incremental
launcher.settings.post_cleanup = post_cleanup
launcher.settings.post_cleanup_purge = post_cleanup_purge
launcher.settings.scrub_old_runs = scrub
launcher.settings.debug = options.debug
f = launcher.run(
flow,
Expand All @@ -318,7 +334,6 @@ def run(
select_design_in_project=select_design_in_project,
design_overrides=design_overrides,
design_allow_extra=design_allow_extra,
design_remove_extra=["lwc"],
)
sys.exit(1 if not f or not f.results.success else 0)
except FlowFatalError as e:
Expand Down Expand Up @@ -585,7 +600,6 @@ def dse(
design=design or design_name,
flow_settings=list(flow_settings),
select_design_in_project=select_design_in_project,
design_remove_extra=["lwc"],
design_allow_extra=design_allow_extra,
)

Expand Down
51 changes: 36 additions & 15 deletions src/xeda/cocotb.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from junitparser import JUnitXml # type: ignore[import-untyped, attr-defined]

from .dataclass import Field, XedaBaseModel, validator
from .design import Design
from .design import Design, SourceType
from .tool import Tool

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -104,38 +104,59 @@ def env(self, design: Design) -> Dict[str, Any]:
ret = {}
if design.tb.cocotb:
if design.tb is None or not design.tb.sources:
raise ValueError("'design.tb.cocotb' is true, but 'design.tb.sources' is empty.")
raise ValueError("'design.tb.cocotb' is set, but 'design.tb.sources' is empty.")
if not design.tb.top:
if not design.rtl.top:
raise ValueError(
f"[cocotb] In design {design.name}: Either `tb.top` or `rtl.top` must be specified."
)
design.tb.top = (design.rtl.top,)
coco_module = design.tb.sources[0].file.stem
tb_top_path = design.tb.sources[0].file.parent
ppath = []
current_ppath = os.environ.get("PYTHONPATH")
if current_ppath:
ppath = current_ppath.split(os.pathsep)
ppath.append(str(tb_top_path))
top: str = design.tb.top if isinstance(design.tb.top, str) else design.tb.top[0]
cocotb_sources = design.sources_of_type(SourceType.Cocotb, rtl=False, tb=True)
if cocotb_sources:
top_cocotb_source = cocotb_sources[-1].file
else:
top_cocotb_source = None

py_path = []
current_py_path = os.environ.get("PYTHONPATH")
if current_py_path:
py_path += current_py_path.split(os.pathsep)
coco_module = None
if design.tb.cocotb.module:
design_module_split = design.tb.cocotb.module.split("/")
coco_module = design_module_split[-1]
if len(design_module_split) > 1:
module_path = os.sep.join(design_module_split[:-1])
if not os.path.isabs(module_path):
module_path = os.path.join(design.root_path, module_path)
else:
module_path = design.root_path
py_path.append(str(module_path))
elif top_cocotb_source:
coco_module = top_cocotb_source.stem
if top_cocotb_source:
py_path.append(str(top_cocotb_source.parent))
toplevel = design.tb.cocotb.toplevel
if not toplevel and design.tb.top:
toplevel = design.tb.top if isinstance(design.tb.top, str) else design.tb.top[0]
ret = {
"MODULE": coco_module,
"TOPLEVEL": top, # TODO
"TOPLEVEL": toplevel, # TODO
"COCOTB_REDUCED_LOG_FMT": int(self.reduced_log_fmt),
"PYTHONPATH": os.pathsep.join(ppath),
"PYTHONPATH": os.pathsep.join(py_path),
"COCOTB_RESULTS_FILE": self.results_xml,
"COCOTB_RESOLVE_X": self.resolve_x,
}
if self.coverage:
ret["COVERAGE"] = 1
if self.testcase:
ret["TESTCASE"] = ",".join(self.testcase)
testcases = self.testcase or design.tb.cocotb.testcase
if testcases:
ret["TESTCASE"] = ",".join(testcases)
if self.random_seed is not None:
ret["RANDOM_SEED"] = self.random_seed
if self.gpi_extra:
ret["GPI_EXTRA"] = ",".join(self.gpi_extra)
log.info("Cocotb env: %s", ret)
log.debug("Cocotb env: %s", ret)
return ret

@cached_property
Expand Down
Loading

0 comments on commit c0808d7

Please sign in to comment.