diff --git a/tasks.py b/tasks.py index e40f3c9..5e2fb62 100644 --- a/tasks.py +++ b/tasks.py @@ -24,18 +24,45 @@ def bsc_root(c): return Path(l[len(dir_prefix):]) raise RuntimeError("Couldn't locate Bluespec root dir") -def find_verilog_modules(c, modules): - libpaths = [Path("lib"), bsc_root(c) / "Verilog"] +def bluespec_libdirs(*extras): + ret = [] + for x in extras: + x = Path(x) + if not x.is_dir(): + x = x.parent + if not x.is_dir(): + raise ValueError(f"unknown libdir thing {x}") + ret.append(x) + + bsv_dirs = list(sorted(set(p.parent for p in Path("").glob("**/*.bsv")))) + exclude_trees = [Path("hardware"), Path("experiments"), Path("sim")] + ret + for d in bsv_dirs: + if any(d.is_relative_to(x) for x in exclude_trees): + continue + ret.append(d) + ret.append("%/Libraries") + return ":".join(str(s) for s in ret) + +def find_verilog_modules(c, target_dir, modules): + preferred_libpaths = [target_dir, Path("lib"), bsc_root(c) / "Verilog"] ret = [] for module in modules: module_path = None + verilog_path = Path(module).with_suffix(".v") + # Try preferred libpaths first. for p in libpaths: - f = p / Path(module).with_suffix(".v") + f = p / verilog_path if f.is_file(): module_path = f break if module_path is None: - raise RuntimeError(f"Cannot find verilog module {module} in {libpaths}") + # Not in preferred paths, accept anywhere now. + matches = Path("").glob(f"**/{module}.v") + if len(matches) > 1: + raise RuntimeError(f"Multiple candidates for verilog module {module}: {matches}") + elif len(matches) == 0: + raise RuntimeError(f"Cannot find verilog module {module} in {libpaths}") + module_path = matches[0] ret.append(module_path) return ret @@ -82,14 +109,16 @@ def phase(name): print("") @task -def build(c, target="."): +def build(c, target): phase("Compile Bluespec") verilog_files = [] for target in expand_build_target(target): out_info, out_verilog, out_bsc = ensure_build_dirs(target, "info", "verilog", "bsc") + libdirs = bluespec_libdirs(target) print(f"Building {target}") - c.run(f"bsc -aggressive-conditions -check-assert -remove-dollar -remove-empty-rules -remove-false-rules -remove-starved-rules -verilog-filter scripts/basicinout.pl -show-method-conf -show-method-bvi -u -verilog -info-dir {out_info} -vdir {out_verilog} -bdir {out_bsc} -p {target.parent}:vram:lib:%/Libraries -show-module-use -show-compiles {target}") + print(f"Libdirs: {libdirs.replace(':', ', ')}") + c.run(f"bsc -aggressive-conditions -check-assert -remove-dollar -remove-empty-rules -remove-false-rules -remove-starved-rules -verilog-filter scripts/basicinout.pl -show-method-conf -show-method-bvi -u -verilog -info-dir {out_info} -vdir {out_verilog} -bdir {out_bsc} -p {libdirs} -show-module-use -show-compiles {target}") module_name = Path(f"mk{target.stem}") verilog_main_file = out_verilog / module_name.with_suffix(".v") @@ -98,7 +127,7 @@ def build(c, target="."): use_file = out_verilog / module_name.with_suffix(".use") if use_file.is_file(): with open(out_verilog / module_name.with_suffix(".use")) as f: - verilog_files.extend(find_verilog_modules(c, f.read().splitlines())) + verilog_files.extend(find_verilog_modules(c, target.parent, f.read().splitlines())) if verilog_files: print("\nVerilog files for synthesis:") @@ -187,7 +216,9 @@ def synth(c, target): def test(c, target): for target in expand_test_target(target): out_info, out_sim, out_bsc = ensure_build_dirs(target, "info", "sim", "bsc") - c.run(f"bsc -show-schedule -aggressive-conditions -check-assert -u -sim -info-dir {out_info} -simdir {out_sim} -bdir {out_bsc} -g mkTB -p {target.parent}:lib:sim:%/Libraries {target}") + libdirs = bluespec_libdirs(target, "sim") + print(f"Libdirs: {libdirs.replace(':', ', ')}") + c.run(f"bsc -show-schedule -aggressive-conditions -check-assert -u -sim -info-dir {out_info} -simdir {out_sim} -bdir {out_bsc} -g mkTB -p {libdirs} {target}") exec = out_sim / "TB" c.run(f"bsc -p {out_bsc} -sim -simdir {out_sim} -e mkTB -o {exec}") testdata = out_sim / "testdata"