From 5928cf8a2a8a400de923ed0fa8a08e40d2da9498 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Thu, 2 Nov 2023 10:50:30 -0600 Subject: [PATCH 1/7] restructure project to begin splitting vivado impl and synth --- .../{ => vivado}/impl/viv_impl.ninja.mustache | 0 .../{ => vivado}/impl/viv_impl.tcl.mustache | 0 .../synth/viv_synth.ninja.mustache | 0 .../{ => vivado}/synth/viv_synth.tcl.mustache | 0 .../ninja_tools/vivado/synth/vivado_synth.py | 51 +++++++++++++++++++ 5 files changed, 51 insertions(+) rename bfasst/ninja_tools/{ => vivado}/impl/viv_impl.ninja.mustache (100%) rename bfasst/ninja_tools/{ => vivado}/impl/viv_impl.tcl.mustache (100%) rename bfasst/ninja_tools/{ => vivado}/synth/viv_synth.ninja.mustache (100%) rename bfasst/ninja_tools/{ => vivado}/synth/viv_synth.tcl.mustache (100%) create mode 100644 bfasst/ninja_tools/vivado/synth/vivado_synth.py diff --git a/bfasst/ninja_tools/impl/viv_impl.ninja.mustache b/bfasst/ninja_tools/vivado/impl/viv_impl.ninja.mustache similarity index 100% rename from bfasst/ninja_tools/impl/viv_impl.ninja.mustache rename to bfasst/ninja_tools/vivado/impl/viv_impl.ninja.mustache diff --git a/bfasst/ninja_tools/impl/viv_impl.tcl.mustache b/bfasst/ninja_tools/vivado/impl/viv_impl.tcl.mustache similarity index 100% rename from bfasst/ninja_tools/impl/viv_impl.tcl.mustache rename to bfasst/ninja_tools/vivado/impl/viv_impl.tcl.mustache diff --git a/bfasst/ninja_tools/synth/viv_synth.ninja.mustache b/bfasst/ninja_tools/vivado/synth/viv_synth.ninja.mustache similarity index 100% rename from bfasst/ninja_tools/synth/viv_synth.ninja.mustache rename to bfasst/ninja_tools/vivado/synth/viv_synth.ninja.mustache diff --git a/bfasst/ninja_tools/synth/viv_synth.tcl.mustache b/bfasst/ninja_tools/vivado/synth/viv_synth.tcl.mustache similarity index 100% rename from bfasst/ninja_tools/synth/viv_synth.tcl.mustache rename to bfasst/ninja_tools/vivado/synth/viv_synth.tcl.mustache diff --git a/bfasst/ninja_tools/vivado/synth/vivado_synth.py b/bfasst/ninja_tools/vivado/synth/vivado_synth.py new file mode 100644 index 000000000..006407c83 --- /dev/null +++ b/bfasst/ninja_tools/vivado/synth/vivado_synth.py @@ -0,0 +1,51 @@ +"""Tool to create Vivado synthesis ninja snippets.""" +import json +from pathlib import Path +import chevron +from bfasst import config +from bfasst.ninja_tools.tool import Tool +from bfasst.utils import compare_json +from bfasst.yaml_parser import YamlParser + + +class VivadoSynth(Tool): + """Tool to create vivado synthesis ninja snippets.""" + + def __init__(self, design, flow_args=None, ooc=False): + super().__init__(design) + self.flow_args = flow_args + + self.ooc = ooc + if ooc: + self.build_path = self.design_build_path / "ooc" / "synth" + else: + self.build_path = self.design_build_path / "in_context" / "synth" + + self._create_build_dir() + + self.top = YamlParser(self.design_path / "design.yaml").parse_top_module() + + # outputs must be initialized AFTER output paths are set + self._init_outputs() + + self._read_hdl_files() + self.vhdl_file_lib_map = {} + self.__read_vhdl_libs() + + self.part = config.PART + + def __read_vhdl_libs(self): + if not self.vhdl_libs: + return + + for lib in self.vhdl_libs: + path = self.design_path / lib + for file in path.rglob("*"): + if file.is_dir(): + continue + if file.suffix == ".vhd": + key = str(file) + self.vhdl_file_lib_map[key] = Path(lib).name + + def create_rule_snippets(self): + return super().create_rule_snippets() From c8096cf7b7d9bd73f3fdf484926804d507fb0e49 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Thu, 2 Nov 2023 16:03:31 -0600 Subject: [PATCH 2/7] finished basic structure of separate vivsynth and vivimpl classes --- bfasst/ninja_tools/vivado/impl/vivado_impl.py | 93 +++++++++++++++++++ .../ninja_tools/vivado/synth/vivado_synth.py | 67 ++++++++++++- bfasst/paths.py | 6 +- 3 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 bfasst/ninja_tools/vivado/impl/vivado_impl.py diff --git a/bfasst/ninja_tools/vivado/impl/vivado_impl.py b/bfasst/ninja_tools/vivado/impl/vivado_impl.py new file mode 100644 index 000000000..68136fe54 --- /dev/null +++ b/bfasst/ninja_tools/vivado/impl/vivado_impl.py @@ -0,0 +1,93 @@ +"""Tool to create Vivado implementation ninja snippets.""" +import json +from pathlib import Path +import chevron +from bfasst import config +from bfasst.ninja_tools.tool import Tool +from bfasst.paths import ( + NINJA_VIVADO_IMPL_TOOL_PATH, + NINJA_BUILD_PATH, +) +from bfasst.utils import compare_json +from bfasst.yaml_parser import YamlParser + + +class VivadoImpl(Tool): + """Tool to create Vivado implementation ninja snippets.""" + + def __init__(self, design, ooc=False): + super().__init__(design) + self.ooc = ooc + if ooc: + self.build_path = self.design_build_path / "ooc" / "impl" + else: + self.build_path = self.design_build_path / "in_context" / "impl" + + self._create_build_dir() + + self.top = YamlParser(self.design_path / "design.yaml").parse_top_module() + + # outputs must be initialized AFTER output paths are set + self._init_outputs() + + self._read_hdl_files() + self.vhdl_file_lib_map = {} + self.__read_vhdl_libs() + + self.part = config.PART + + def __write_json_file(self): + """Specify implementation arguments in a json file. + Chevron will use the file to fill in the tcl template.""" + impl = { + "part": self.part, + "xdc": str(self.build_path.parent / "synth" / (self.top + ".xdc")) + if not self.ooc + else False, + "bit": str(self.build_path / (self.top + ".bit")) if not self.ooc else False, + "impl_output": str(self.build_path), + "synth_output": str(self.build_path.parent / "synth"), + } + impl_json = json.dumps(impl, indent=4) + + # check if the impl json file alread exists and compare it to what we're about to write. + json_equivalent = compare_json(self.build_path / "impl.json", impl_json) + + if not json_equivalent: + with open(self.build_path / "impl.json", "w") as f: + f.write(impl_json) + + def __append_build_snippets(self): + """Create ninja snippets for vivado implementation in build.ninja""" + with open(NINJA_VIVADO_IMPL_TOOL_PATH / "viv_impl.ninja.mustache") as f: + impl_ninja = chevron.render( + f, + { + "in_context": not self.ooc, + "impl_output": str(self.build_path), + "synth_output": str(self.build_path.parent / "synth"), + "impl_library": NINJA_VIVADO_IMPL_TOOL_PATH, + "top": self.top, + }, + ) + + with open(NINJA_BUILD_PATH, "a") as f: + f.write(impl_ninja) + + def _init_outputs(self): + self.outputs["impl_tcl"] = self.build_path / "impl.tcl" + self.outputs["impl_json"] = self.build_path / "impl.json" + self.outputs["impl_verilog"] = self.build_path / "viv_impl.v" + self.outputs["impl_edf"] = self.build_path / "viv_impl.edf" + self.outputs["impl_checkpoint"] = self.build_path / "impl.dcp" + self.outputs["utilization"] = self.build_path / "utiliztion.txt" + self.outputs["impl_journal"] = self.build_path / "vivado.jou" + self.outputs["impl_log"] = self.build_path / "vivado.log" + + if not self.ooc: + self.outputs["bitstream"] = self.build_path / (self.top + ".bit") + + def add_ninja_deps(self, deps): + """Add dependencies to the master ninja file that would cause it to rebuild if modified.""" + self._add_ninja_deps_default(deps, __file__) + deps.append(NINJA_VIVADO_IMPL_TOOL_PATH / "viv_impl.ninja.mustache") diff --git a/bfasst/ninja_tools/vivado/synth/vivado_synth.py b/bfasst/ninja_tools/vivado/synth/vivado_synth.py index 006407c83..9dc932962 100644 --- a/bfasst/ninja_tools/vivado/synth/vivado_synth.py +++ b/bfasst/ninja_tools/vivado/synth/vivado_synth.py @@ -1,9 +1,9 @@ """Tool to create Vivado synthesis ninja snippets.""" import json -from pathlib import Path import chevron from bfasst import config from bfasst.ninja_tools.tool import Tool +from bfasst.paths import NINJA_BUILD_PATH, NINJA_VIVADO_SYNTH_TOOL_PATH from bfasst.utils import compare_json from bfasst.yaml_parser import YamlParser @@ -48,4 +48,67 @@ def __read_vhdl_libs(self): self.vhdl_file_lib_map[key] = Path(lib).name def create_rule_snippets(self): - return super().create_rule_snippets() + if not self.rule_snippets_exist: + super().create_rule_snippets(self.ooc) + + def create_build_snippets(self): + self.__write_json_file() + self.__append_build_snippets() + + def __write_json_file(self): + """Specify synthesis arguments in a json file. + Chevron will use this file to fill in the tcl template.""" + synth = { + "part": self.part, + "top": self.top, + "vhdl": self.vhdl, + "vhdl_libs": list(self.vhdl_file_lib_map.items()), + "verilog": self.verilog, + "system_verilog": self.system_verilog, + "io": str(self.build_path / "report_io.txt") if not self.ooc else False, + "synth_output": str(self.build_path), + "flow_args": self.flow_args if self.flow_args else "", + } + synth_json = json.dumps(synth, indent=4) + + # check if json file already exists and compare it to what we're about to write + json_equivalent = compare_json(self.build_path / "synth.json", synth_json) + + if not json_equivalent: + with open(self.build_path / "synth.json", "w") as f: + f.write(synth_json) + + def __append_build_snippets(self): + """Create ninja snippets for vivado synthesis in build.ninja""" + with open(NINJA_VIVADO_SYNTH_TOOL_PATH / "viv_synth.ninja.mustache") as f: + synth_ninja = chevron.render( + f, + { + "in_context": not self.ooc, + "synth_output": str(self.build_path), + "synth_library": NINJA_VIVADO_SYNTH_TOOL_PATH, + "top": self.top, + "verilog": self.verilog, + "system_verilog": self.system_verilog, + }, + ) + + with open(NINJA_BUILD_PATH, "a") as f: + f.write(synth_ninja) + + def _init_outputs(self): + self.outputs["synth_tcl"] = self.build_path / "synth.tcl" + self.outputs["synth_json"] = self.build_path / "synth.json" + self.outputs["synth_edf"] = self.build_path / "viv_synth.edf" + self.outputs["synth_dcp"] = self.build_path / "synth.dcp" + self.outputs["synth_journal"] = self.build_path / "vivado.jou" + self.outputs["synth_log"] = self.build_path / "vivado.log" + + if not self.ooc: + self.outputs["io_report"] = self.build_path / "report_io.txt" + self.outputs["synth_constraints"] = self.build_path / (self.top + ".xdc") + + def add_ninja_deps(self, deps): + """Add dependencies to the master ninja file that would cause it to rebuild if modified""" + self._add_ninja_deps_default(deps, __file__) + deps.append(NINJA_VIVADO_SYNTH_TOOL_PATH / "viv_synth.ninja.mustache") diff --git a/bfasst/paths.py b/bfasst/paths.py index eb104e3ba..d4ee35f43 100644 --- a/bfasst/paths.py +++ b/bfasst/paths.py @@ -19,10 +19,10 @@ NINJA_UTILS_PATH = BFASST_PATH / "ninja_utils" NINJA_FLOWS_PATH = BFASST_PATH / "ninja_flows" -NINJA_SYNTH_TOOLS_PATH = NINJA_TOOLS_PATH / "synth" -NINJA_IMPL_TOOLS_PATH = NINJA_TOOLS_PATH / "impl" -VIVADO_RULES_PATH = NINJA_TOOLS_PATH / "vivado" / "vivado_rules.ninja.mustache" NINJA_VIVADO_TOOLS_PATH = NINJA_TOOLS_PATH / "vivado" +NINJA_VIVADO_SYNTH_TOOL_PATH = NINJA_VIVADO_TOOLS_PATH / "synth" +NINJA_VIVADO_IMPL_TOOL_PATH = NINJA_VIVADO_TOOLS_PATH / "impl" +VIVADO_RULES_PATH = NINJA_TOOLS_PATH / "vivado" / "vivado_rules.ninja.mustache" REV_BIT_TOOLS_PATH = NINJA_TOOLS_PATH / "rev_bit" NINJA_TRANSFORM_TOOLS_PATH = NINJA_TOOLS_PATH / "transform" From 9078e3792aac7411c232a75625377f0b7cc43223 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Thu, 2 Nov 2023 16:50:05 -0600 Subject: [PATCH 3/7] added parent class for vivado tools, changed flows accordingly --- bfasst/ninja_flows/flow.py | 8 +- bfasst/ninja_flows/vivado.py | 13 +- bfasst/ninja_flows/vivado_bit_analysis.py | 15 +- bfasst/ninja_flows/vivado_conformal.py | 17 +- bfasst/ninja_flows/vivado_phys_netlist.py | 17 +- bfasst/ninja_flows/vivado_phys_netlist_cmp.py | 19 +- .../ninja_flows/vivado_phys_netlist_xrev.py | 19 +- .../vivado_structural_error_injection.py | 19 +- bfasst/ninja_flows/vivado_yosys_impl.py | 17 +- bfasst/ninja_tools/vivado/impl/vivado_impl.py | 37 +--- .../ninja_tools/vivado/synth/vivado_synth.py | 57 +----- bfasst/ninja_tools/vivado/vivado.py | 186 ++++-------------- 12 files changed, 148 insertions(+), 276 deletions(-) diff --git a/bfasst/ninja_flows/flow.py b/bfasst/ninja_flows/flow.py index de141a1af..2a4add5e7 100644 --- a/bfasst/ninja_flows/flow.py +++ b/bfasst/ninja_flows/flow.py @@ -1,7 +1,7 @@ """Base class for all ninja flows""" import abc -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.paths import BUILD_DIR, DESIGNS_PATH @@ -29,7 +29,7 @@ def add_ninja_deps(self): def get_top_level_flow_path(self) -> str: """Get the path to the top level flow file for this flow""" - def configure_vivado_tool(self, design, flow_args, ooc=False): + def configure_vivado_synth_tool(self, design, flow_args, ooc=False): if isinstance(flow_args, dict) and "synth" in flow_args: - return Vivado(design, flow_args["synth"], ooc) - return Vivado(design, ooc=ooc) + return VivadoSynth(design, flow_args["synth"], ooc) + return VivadoSynth(design, ooc=ooc) diff --git a/bfasst/ninja_flows/vivado.py b/bfasst/ninja_flows/vivado.py index 031836733..6f93ff3d3 100644 --- a/bfasst/ninja_flows/vivado.py +++ b/bfasst/ninja_flows/vivado.py @@ -1,5 +1,6 @@ """Flow to create Vivado synthesis and implementation ninja snippets.""" from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import NINJA_FLOWS_PATH @@ -9,16 +10,20 @@ class Vivado(Flow): def __init__(self, design, flow_args=None, ooc=False): super().__init__(design) self.ooc = ooc - self.vivado_tool = self.configure_vivado_tool(design, flow_args, ooc) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args, ooc) + self.vivado_impl_tool = VivadoImpl(design, ooc) def create_rule_snippets(self): - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) deps.append(NINJA_FLOWS_PATH / "vivado.py") if self.ooc: deps.append(NINJA_FLOWS_PATH / "vivado_ooc.py") diff --git a/bfasst/ninja_flows/vivado_bit_analysis.py b/bfasst/ninja_flows/vivado_bit_analysis.py index ab79b67ac..0617e1ddf 100644 --- a/bfasst/ninja_flows/vivado_bit_analysis.py +++ b/bfasst/ninja_flows/vivado_bit_analysis.py @@ -3,6 +3,7 @@ import pathlib from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.rev_bit.xray import Xray as XrevTool from bfasst.ninja_tools.transform.netlist_cleanup import NetlistCleanupTool from bfasst.ninja_tools.transform.netlist_phys_to_logical import NetlistPhysToLogicalTool @@ -13,20 +14,23 @@ class VivadoBitAnalysis(Flow): def __init__(self, design, flow_args=None): super().__init__(design) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.xrev_tool = XrevTool(design) self.netlist_cleanup_tool = NetlistCleanupTool(design) self.netlist_phys_to_logical = NetlistPhysToLogicalTool(design) def create_rule_snippets(self): - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.xrev_tool.create_rule_snippets() self.netlist_cleanup_tool.create_rule_snippets() self.netlist_phys_to_logical.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() - self.xrev_tool.create_build_snippets(str(self.vivado_tool.outputs["bitstream"])) + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() + self.xrev_tool.create_build_snippets(str(self.vivado_impl_tool.outputs["bitstream"])) self.netlist_cleanup_tool.create_build_snippets( netlist_in_path=self.xrev_tool.outputs["xray_netlist"], ) @@ -35,7 +39,8 @@ def create_build_snippets(self): ) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.xrev_tool.add_ninja_deps(deps) self.netlist_cleanup_tool.add_ninja_deps(deps) self.netlist_phys_to_logical.add_ninja_deps(deps) diff --git a/bfasst/ninja_flows/vivado_conformal.py b/bfasst/ninja_flows/vivado_conformal.py index 4bb775214..290c6b01f 100644 --- a/bfasst/ninja_flows/vivado_conformal.py +++ b/bfasst/ninja_flows/vivado_conformal.py @@ -1,6 +1,7 @@ """Run vivado, phys_netlist, reverse with xray, then compare with conformal.""" from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.compare.conformal.conformal import Conformal from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.paths import NINJA_FLOWS_PATH @@ -12,26 +13,30 @@ class VivadoConformal(Flow): def __init__(self, design, flow_args=None): super().__init__(design) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.xrev_tool = Xray(design) self.conformal_tool = Conformal(design) def create_rule_snippets(self): - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.xrev_tool.create_rule_snippets() self.conformal_tool.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() - self.xrev_tool.create_build_snippets(str(self.vivado_tool.outputs["bitstream"])) + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() + self.xrev_tool.create_build_snippets(str(self.vivado_impl_tool.outputs["bitstream"])) self.conformal_tool.create_build_snippets( - impl_netlist=str(self.vivado_tool.outputs["impl_verilog"]), + impl_netlist=str(self.vivado_impl_tool.outputs["impl_verilog"]), rev_netlist=str(self.xrev_tool.outputs["xray_netlist"]), vendor=Vendor.XILINX, ) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.xrev_tool.add_ninja_deps(deps) self.conformal_tool.add_ninja_deps(deps) deps.append(NINJA_FLOWS_PATH / "vivado_conformal.py") diff --git a/bfasst/ninja_flows/vivado_phys_netlist.py b/bfasst/ninja_flows/vivado_phys_netlist.py index d848cf071..5a5172c20 100644 --- a/bfasst/ninja_flows/vivado_phys_netlist.py +++ b/bfasst/ninja_flows/vivado_phys_netlist.py @@ -1,6 +1,7 @@ """Creates a Vivado netlist that has only physical primitives.""" from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist from bfasst.paths import NINJA_FLOWS_PATH @@ -10,22 +11,26 @@ class VivadoPhysNetlist(Flow): def __init__(self, design, flow_args=None): super().__init__(design) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.phys_netlist_tool = PhysNetlist(design) def create_rule_snippets(self): - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.phys_netlist_tool.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() self.phys_netlist_tool.create_build_snippets( - impl_dcp=self.vivado_tool.outputs["impl_checkpoint"], - impl_edf=self.vivado_tool.outputs["impl_edf"], + impl_dcp=self.vivado_impl_tool.outputs["impl_checkpoint"], + impl_edf=self.vivado_impl_tool.outputs["impl_edf"], ) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.phys_netlist_tool.add_ninja_deps(deps) deps.append(NINJA_FLOWS_PATH / "vivado_phys_netlist.py") diff --git a/bfasst/ninja_flows/vivado_phys_netlist_cmp.py b/bfasst/ninja_flows/vivado_phys_netlist_cmp.py index 3b59d61e0..7959b55d4 100644 --- a/bfasst/ninja_flows/vivado_phys_netlist_cmp.py +++ b/bfasst/ninja_flows/vivado_phys_netlist_cmp.py @@ -1,6 +1,7 @@ """Structural Comparison of physical netlist and reversed netlist""" from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.compare.structural.structural import Structural from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist @@ -12,24 +13,27 @@ class VivadoPhysNetlistCmp(Flow): def __init__(self, design, flow_args=None): super().__init__(design) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.phys_netlist_tool = PhysNetlist(design) self.xray_tool = Xray(design) self.compare_tool = Structural(design) def create_rule_snippets(self): - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.phys_netlist_tool.create_rule_snippets() self.xray_tool.create_rule_snippets() self.compare_tool.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() self.phys_netlist_tool.create_build_snippets( - impl_dcp=self.vivado_tool.outputs["impl_checkpoint"], - impl_edf=self.vivado_tool.outputs["impl_edf"], + impl_dcp=self.vivado_impl_tool.outputs["impl_checkpoint"], + impl_edf=self.vivado_impl_tool.outputs["impl_edf"], ) - self.xray_tool.create_build_snippets(str(self.vivado_tool.outputs["bitstream"])) + self.xray_tool.create_build_snippets(str(self.vivado_impl_tool.outputs["bitstream"])) self.compare_tool.create_build_snippets( netlist_a=self.xray_tool.outputs["xray_netlist"], netlist_b=self.phys_netlist_tool.outputs["viv_impl_physical_v"], @@ -37,7 +41,8 @@ def create_build_snippets(self): ) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.phys_netlist_tool.add_ninja_deps(deps) self.xray_tool.add_ninja_deps(deps) self.compare_tool.add_ninja_deps(deps) diff --git a/bfasst/ninja_flows/vivado_phys_netlist_xrev.py b/bfasst/ninja_flows/vivado_phys_netlist_xrev.py index b00ba6947..2cd104080 100644 --- a/bfasst/ninja_flows/vivado_phys_netlist_xrev.py +++ b/bfasst/ninja_flows/vivado_phys_netlist_xrev.py @@ -2,6 +2,7 @@ from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist from bfasst.paths import NINJA_FLOWS_PATH @@ -12,27 +13,31 @@ class VivadoPhysNetlistXrev(Flow): def __init__(self, design, flow_args=None): super().__init__(design) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.phys_netlist_tool = PhysNetlist(design) self.xrev_tool = Xray(design) def create_rule_snippets(self): """Create the rule snippets for the flow and append them to build.ninja.""" - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.phys_netlist_tool.create_rule_snippets() self.xrev_tool.create_rule_snippets() def create_build_snippets(self): """Create the build snippets for the flow and append them to build.ninja.""" - self.vivado_tool.create_build_snippets() + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() self.phys_netlist_tool.create_build_snippets( - impl_dcp=self.vivado_tool.outputs["impl_checkpoint"], - impl_edf=self.vivado_tool.outputs["impl_edf"], + impl_dcp=self.vivado_impl_tool.outputs["impl_checkpoint"], + impl_edf=self.vivado_impl_tool.outputs["impl_edf"], ) - self.xrev_tool.create_build_snippets(self.vivado_tool.outputs["bitstream"]) + self.xrev_tool.create_build_snippets(self.vivado_impl_tool.outputs["bitstream"]) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.phys_netlist_tool.add_ninja_deps(deps) self.xrev_tool.add_ninja_deps(deps) deps.append(NINJA_FLOWS_PATH / "vivado_phys_netlist_xrev.py") diff --git a/bfasst/ninja_flows/vivado_structural_error_injection.py b/bfasst/ninja_flows/vivado_structural_error_injection.py index eaf041af2..3a4f069d4 100644 --- a/bfasst/ninja_flows/vivado_structural_error_injection.py +++ b/bfasst/ninja_flows/vivado_structural_error_injection.py @@ -3,6 +3,7 @@ import random from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.compare.structural.structural import Structural from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.error_injector import ErrorInjector @@ -18,7 +19,8 @@ class VivadoStructuralErrorInjection(Flow): def __init__(self, design, flow_args=None): super().__init__(design) random.seed(0) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.phys_netlist_tool = PhysNetlist(design) self.xrev_tool = Xray(design) self.error_injector_tool = ErrorInjector(design) @@ -28,19 +30,21 @@ def __init__(self, design, flow_args=None): def create_rule_snippets(self): """Create the rule snippets for the flow and append them to build.ninja.""" - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.phys_netlist_tool.create_rule_snippets() self.xrev_tool.create_rule_snippets() self.error_injector_tool.create_rule_snippets() self.compare_tool.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() self.phys_netlist_tool.create_build_snippets( - impl_dcp=self.vivado_tool.outputs["impl_checkpoint"], - impl_edf=self.vivado_tool.outputs["impl_edf"], + impl_dcp=self.vivado_impl_tool.outputs["impl_checkpoint"], + impl_edf=self.vivado_impl_tool.outputs["impl_edf"], ) - self.xrev_tool.create_build_snippets(self.vivado_tool.outputs["bitstream"]) + self.xrev_tool.create_build_snippets(self.vivado_impl_tool.outputs["bitstream"]) random_seed_multiplier = 1 error_type = [ErrorType.BIT_FLIP, ErrorType.WIRE_SWAP] @@ -62,7 +66,8 @@ def create_build_snippets(self): ) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.phys_netlist_tool.add_ninja_deps(deps) self.xrev_tool.add_ninja_deps(deps) self.error_injector_tool.add_ninja_deps(deps) diff --git a/bfasst/ninja_flows/vivado_yosys_impl.py b/bfasst/ninja_flows/vivado_yosys_impl.py index 8aa2bdd49..17d105714 100644 --- a/bfasst/ninja_flows/vivado_yosys_impl.py +++ b/bfasst/ninja_flows/vivado_yosys_impl.py @@ -1,5 +1,6 @@ """Flow to compare reversed netlist to original using yosys.""" from bfasst.ninja_flows.flow import Flow +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.compare.yosys.yosys import Yosys from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.paths import NINJA_FLOWS_PATH @@ -10,25 +11,29 @@ class VivadoYosysImpl(Flow): def __init__(self, design, flow_args=None): super().__init__(design) - self.vivado_tool = self.configure_vivado_tool(design, flow_args) + self.vivado_synth_tool = self.configure_vivado_synth_tool(design, flow_args) + self.vivado_impl_tool = VivadoImpl(design) self.xrev_tool = Xray(design) self.yosys_tool = Yosys(design) def create_rule_snippets(self): - self.vivado_tool.create_rule_snippets() + self.vivado_synth_tool.create_rule_snippets() + self.vivado_impl_tool.create_rule_snippets() self.xrev_tool.create_rule_snippets() self.yosys_tool.create_rule_snippets() def create_build_snippets(self): - self.vivado_tool.create_build_snippets() - self.xrev_tool.create_build_snippets(str(self.vivado_tool.outputs["bitstream"])) + self.vivado_synth_tool.create_build_snippets() + self.vivado_impl_tool.create_build_snippets() + self.xrev_tool.create_build_snippets(str(self.vivado_impl_tool.outputs["bitstream"])) self.yosys_tool.create_build_snippets( - gold_netlist=self.vivado_tool.outputs["impl_verilog"], + gold_netlist=self.vivado_impl_tool.outputs["impl_verilog"], rev_netlist=self.xrev_tool.outputs["xray_netlist"], ) def add_ninja_deps(self, deps): - self.vivado_tool.add_ninja_deps(deps) + self.vivado_synth_tool.add_ninja_deps(deps) + self.vivado_impl_tool.add_ninja_deps(deps) self.xrev_tool.add_ninja_deps(deps) self.yosys_tool.add_ninja_deps(deps) deps.append(NINJA_FLOWS_PATH / "vivado_yosys_impl.py") diff --git a/bfasst/ninja_tools/vivado/impl/vivado_impl.py b/bfasst/ninja_tools/vivado/impl/vivado_impl.py index 68136fe54..84414c7b7 100644 --- a/bfasst/ninja_tools/vivado/impl/vivado_impl.py +++ b/bfasst/ninja_tools/vivado/impl/vivado_impl.py @@ -1,42 +1,24 @@ """Tool to create Vivado implementation ninja snippets.""" import json -from pathlib import Path import chevron -from bfasst import config -from bfasst.ninja_tools.tool import Tool +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( NINJA_VIVADO_IMPL_TOOL_PATH, NINJA_BUILD_PATH, ) -from bfasst.utils import compare_json -from bfasst.yaml_parser import YamlParser -class VivadoImpl(Tool): +class VivadoImpl(Vivado): """Tool to create Vivado implementation ninja snippets.""" def __init__(self, design, ooc=False): - super().__init__(design) - self.ooc = ooc - if ooc: - self.build_path = self.design_build_path / "ooc" / "impl" - else: - self.build_path = self.design_build_path / "in_context" / "impl" - - self._create_build_dir() - - self.top = YamlParser(self.design_path / "design.yaml").parse_top_module() + super().__init__(design, ooc) + self.build_path = self.design_build_path / "impl" # outputs must be initialized AFTER output paths are set self._init_outputs() - self._read_hdl_files() - self.vhdl_file_lib_map = {} - self.__read_vhdl_libs() - - self.part = config.PART - - def __write_json_file(self): + def _write_json_file(self): """Specify implementation arguments in a json file. Chevron will use the file to fill in the tcl template.""" impl = { @@ -50,14 +32,9 @@ def __write_json_file(self): } impl_json = json.dumps(impl, indent=4) - # check if the impl json file alread exists and compare it to what we're about to write. - json_equivalent = compare_json(self.build_path / "impl.json", impl_json) - - if not json_equivalent: - with open(self.build_path / "impl.json", "w") as f: - f.write(impl_json) + self._json_write(self.build_path / "impl.json", impl_json) - def __append_build_snippets(self): + def _append_build_snippets(self): """Create ninja snippets for vivado implementation in build.ninja""" with open(NINJA_VIVADO_IMPL_TOOL_PATH / "viv_impl.ninja.mustache") as f: impl_ninja = chevron.render( diff --git a/bfasst/ninja_tools/vivado/synth/vivado_synth.py b/bfasst/ninja_tools/vivado/synth/vivado_synth.py index 9dc932962..a7c4116a8 100644 --- a/bfasst/ninja_tools/vivado/synth/vivado_synth.py +++ b/bfasst/ninja_tools/vivado/synth/vivado_synth.py @@ -1,61 +1,23 @@ """Tool to create Vivado synthesis ninja snippets.""" import json import chevron -from bfasst import config -from bfasst.ninja_tools.tool import Tool +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import NINJA_BUILD_PATH, NINJA_VIVADO_SYNTH_TOOL_PATH -from bfasst.utils import compare_json -from bfasst.yaml_parser import YamlParser -class VivadoSynth(Tool): +class VivadoSynth(Vivado): """Tool to create vivado synthesis ninja snippets.""" def __init__(self, design, flow_args=None, ooc=False): - super().__init__(design) + super().__init__(design, ooc) self.flow_args = flow_args - self.ooc = ooc - if ooc: - self.build_path = self.design_build_path / "ooc" / "synth" - else: - self.build_path = self.design_build_path / "in_context" / "synth" - - self._create_build_dir() - - self.top = YamlParser(self.design_path / "design.yaml").parse_top_module() + self.build_path = self.build_path / "synth" # outputs must be initialized AFTER output paths are set self._init_outputs() - self._read_hdl_files() - self.vhdl_file_lib_map = {} - self.__read_vhdl_libs() - - self.part = config.PART - - def __read_vhdl_libs(self): - if not self.vhdl_libs: - return - - for lib in self.vhdl_libs: - path = self.design_path / lib - for file in path.rglob("*"): - if file.is_dir(): - continue - if file.suffix == ".vhd": - key = str(file) - self.vhdl_file_lib_map[key] = Path(lib).name - - def create_rule_snippets(self): - if not self.rule_snippets_exist: - super().create_rule_snippets(self.ooc) - - def create_build_snippets(self): - self.__write_json_file() - self.__append_build_snippets() - - def __write_json_file(self): + def _write_json_file(self): """Specify synthesis arguments in a json file. Chevron will use this file to fill in the tcl template.""" synth = { @@ -71,14 +33,9 @@ def __write_json_file(self): } synth_json = json.dumps(synth, indent=4) - # check if json file already exists and compare it to what we're about to write - json_equivalent = compare_json(self.build_path / "synth.json", synth_json) - - if not json_equivalent: - with open(self.build_path / "synth.json", "w") as f: - f.write(synth_json) + self._json_write(self.build_path / "synth.json", synth_json) - def __append_build_snippets(self): + def _append_build_snippets(self): """Create ninja snippets for vivado synthesis in build.ninja""" with open(NINJA_VIVADO_SYNTH_TOOL_PATH / "viv_synth.ninja.mustache") as f: synth_ninja = chevron.render( diff --git a/bfasst/ninja_tools/vivado/vivado.py b/bfasst/ninja_tools/vivado/vivado.py index 3f9b43316..e99b3509d 100644 --- a/bfasst/ninja_tools/vivado/vivado.py +++ b/bfasst/ninja_tools/vivado/vivado.py @@ -1,54 +1,38 @@ -"""Tool to create Vivado synthesis and implementation ninja snippets.""" -import json +"""Parent tool for vivado synth and impl tools.""" from pathlib import Path +from abc import ABC import chevron -from bfasst import config from bfasst.ninja_tools.tool import Tool -from bfasst.paths import ( - NINJA_IMPL_TOOLS_PATH, - NINJA_BUILD_PATH, - NINJA_SYNTH_TOOLS_PATH, - NINJA_UTILS_PATH, - VIVADO_RULES_PATH, -) -from bfasst.utils import compare_json +from bfasst.paths import NINJA_BUILD_PATH, NINJA_UTILS_PATH, VIVADO_RULES_PATH +from bfasst import config +from bfasst.utils.general import compare_json + from bfasst.yaml_parser import YamlParser -class Vivado(Tool): - """Tool to create Vivado synthesis and implementation ninja snippets.""" +class Vivado(Tool, ABC): + """Parent tool for vivado synth and impl tools.""" - def __init__(self, design, flow_args=None, ooc=False): - super().__init__(design) - self.flow_args = flow_args + # Static method to prevent rule duplication across all children tools + rules_appended_to_build = False + def __init__(self, design, ooc=False): + super().__init__(design) self.ooc = ooc if ooc: self.build_path = self.design_build_path / "ooc" else: self.build_path = self.design_build_path / "in_context" - self.synth_output = self.build_path / "synth" - self.impl_output = self.build_path / "impl" self._create_build_dir() - self.top = YamlParser(self.design_path / "design.yaml").parse_top_module() - # outputs must be initialized AFTER output paths are set - self._init_outputs() - self._read_hdl_files() - self.vhdl_file_lib_map = {} self.__read_vhdl_libs() self.part = config.PART - def _create_build_dir(self): - super()._create_build_dir() - self.synth_output.mkdir(exist_ok=True) - self.impl_output.mkdir(exist_ok=True) - def __read_vhdl_libs(self): if not self.vhdl_libs: return @@ -62,131 +46,45 @@ def __read_vhdl_libs(self): key = str(file) self.vhdl_file_lib_map[key] = Path(lib).name + def _create_build_dir(self): + super()._create_build_dir() + def create_rule_snippets(self): - with open(VIVADO_RULES_PATH, "r") as f: - vivado_ninja = chevron.render( - f, - { - "vivado_path": config.VIVADO_BIN_PATH, - "utils": str(NINJA_UTILS_PATH), - "in_context": not self.ooc, - }, - ) - with open(NINJA_BUILD_PATH, "a") as f: - f.write(vivado_ninja) + if not Vivado.rules_appended_to_build: + with open(VIVADO_RULES_PATH, "r") as f: + vivado_ninja = chevron.render( + f, + { + "vivado_path": config.VIVADO_BIN_PATH, + "utils": str(NINJA_UTILS_PATH), + "in_context": not self.ooc, + }, + ) + with open(NINJA_BUILD_PATH, "a") as f: + f.write(vivado_ninja) + Vivado.rules_appended_to_build = True def create_build_snippets(self): - self.__write_json_files() + self.__write_json_file() self.__append_build_snippets() - def __write_json_files(self): - self.__write_synth_json() - self.__write_impl_json() - - def __write_synth_json(self): - """Specify synthesis arguments in a json file. - Chevron will use to fill in the tcl template""" - synth = { - "part": self.part, - "verilog": self.verilog, - "system_verilog": self.system_verilog, - "vhdl": self.vhdl, - "vhdl_libs": list(self.vhdl_file_lib_map.items()), - "top": self.top, - "io": str(self.synth_output / "report_io.txt") if not self.ooc else False, - "synth_output": str(self.synth_output), - "flow_args": self.flow_args if self.flow_args else "", - } - synth_json = json.dumps(synth, indent=4) - - # check if the synth json file already exists and compare it to what we're about to write - json_equivalent = compare_json(self.synth_output / "synth.json", synth_json) + def _json_write(self, old_path, new_string): + """Write the json file for the tool, if the new string + does not match the json already in existence.""" + json_equivalent = compare_json(old_path, new_string) if not json_equivalent: - with open(self.synth_output / "synth.json", "w") as f: - f.write(synth_json) - - def __write_impl_json(self): - """Specify implementation arguments in json file. - Chevron will use json file to fill in the tcl template""" - impl = { - "part": self.part, - "xdc": str(self.synth_output / (self.top + ".xdc")) if not self.ooc else False, - "bit": str(self.impl_output / (self.top + ".bit")) if not self.ooc else False, - "impl_output": str(self.impl_output), - "synth_output": str(self.synth_output), - } - impl_json = json.dumps(impl, indent=4) - - # check if the impl json file already exists and compare it to what we're about to write - json_equivalent = compare_json(self.impl_output / "impl.json", impl_json) + with open(old_path, "w") as f: + f.write(new_string) - if not json_equivalent: - with open(self.impl_output / "impl.json", "w") as f: - f.write(impl_json) + def __write_json_file(self): + pass def __append_build_snippets(self): - self.__append_synth_snippets() - self.__append_impl_snippets() - - def __append_synth_snippets(self): - """Create ninja snippets for vivado synthesis in build.ninja""" - with open(NINJA_SYNTH_TOOLS_PATH / "viv_synth.ninja.mustache") as f: - synth_ninja = chevron.render( - f, - { - "in_context": not self.ooc, - "synth_output": str(self.synth_output), - "synth_library": NINJA_SYNTH_TOOLS_PATH, - "top": self.top, - "verilog": self.verilog, - "system_verilog": self.system_verilog, - }, - ) - - with open(NINJA_BUILD_PATH, "a") as f: - f.write(synth_ninja) - - def __append_impl_snippets(self): - """Create ninja snippets for vivado implementation in build.ninja""" - with open(NINJA_IMPL_TOOLS_PATH / "viv_impl.ninja.mustache") as f: - impl_ninja = chevron.render( - f, - { - "in_context": not self.ooc, - "impl_output": str(self.impl_output), - "synth_output": str(self.synth_output), - "impl_library": NINJA_IMPL_TOOLS_PATH, - "top": self.top, - }, - ) - - with open(NINJA_BUILD_PATH, "a") as f: - f.write(impl_ninja) + pass + + def add_ninja_deps(self): + pass def _init_outputs(self): - self.outputs["synth_tcl"] = self.synth_output / "synth.tcl" - self.outputs["impl_tcl"] = self.impl_output / "impl.tcl" - self.outputs["synth_json"] = self.synth_output / "synth.json" - self.outputs["impl_json"] = self.impl_output / "impl.json" - self.outputs["synth_edf"] = self.synth_output / "viv_synth.edf" - self.outputs["synth_checkpoint"] = self.synth_output / "synth.dcp" - self.outputs["impl_verilog"] = self.impl_output / "viv_impl.v" - self.outputs["impl_edf"] = self.impl_output / "viv_impl.edf" - self.outputs["impl_checkpoint"] = self.impl_output / "impl.dcp" - self.outputs["utilization"] = self.impl_output / "utilization.txt" - self.outputs["impl_journal"] = self.impl_output / "vivado.jou" - self.outputs["impl_log"] = self.impl_output / "vivado.log" - self.outputs["synth_journal"] = self.synth_output / "vivado.jou" - self.outputs["synth_log"] = self.synth_output / "vivado.log" - - if not self.ooc: - self.outputs["io_report"] = self.synth_output / "report_io.txt" - self.outputs["synth_constraints"] = self.synth_output / (self.top + ".xdc") - self.outputs["bitstream"] = self.impl_output / (self.top + ".bit") - - def add_ninja_deps(self, deps): - """Add dependencies to the master ninja file that would cause it to rebuild if modified""" - self._add_ninja_deps_default(deps, __file__) - deps.append(NINJA_SYNTH_TOOLS_PATH / "viv_synth.ninja.mustache") - deps.append(NINJA_IMPL_TOOLS_PATH / "viv_impl.ninja.mustache") + pass From fdc1bc34713d338b16e6fd4886c7d1cd5d7559f6 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Thu, 2 Nov 2023 17:04:41 -0600 Subject: [PATCH 4/7] basic refactoring of unittests due to split of vivado synth and impl tools --- test/flows/test_vivado_bit_analysis_flow.py | 6 ++- test/flows/test_vivado_conformal_flow.py | 6 ++- test/flows/test_vivado_flow.py | 40 +++++++++++-------- test/flows/test_vivado_ooc_flow.py | 26 ++++++------ test/flows/test_vivado_phys_netlist.py | 6 ++- .../test_vivado_phys_netlist_cmp_flow.py | 6 ++- .../test_vivado_phys_netlist_xrev_flow.py | 6 ++- ..._vivado_structural_error_injection_flow.py | 6 ++- test/flows/test_vivado_yosys_impl_flow.py | 6 ++- 9 files changed, 65 insertions(+), 43 deletions(-) diff --git a/test/flows/test_vivado_bit_analysis_flow.py b/test/flows/test_vivado_bit_analysis_flow.py index 807a902bb..fe6ed6a62 100644 --- a/test/flows/test_vivado_bit_analysis_flow.py +++ b/test/flows/test_vivado_bit_analysis_flow.py @@ -10,7 +10,8 @@ from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.netlist_cleanup import NetlistCleanupTool from bfasst.ninja_tools.transform.netlist_phys_to_logical import NetlistPhysToLogicalTool -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -55,7 +56,8 @@ def test_add_ninja_deps(self): expected = ["foo", "bar"] Xray(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) - Vivado(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) NetlistCleanupTool(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) NetlistPhysToLogicalTool(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) diff --git a/test/flows/test_vivado_conformal_flow.py b/test/flows/test_vivado_conformal_flow.py index 074b229c0..9f6b03a8b 100644 --- a/test/flows/test_vivado_conformal_flow.py +++ b/test/flows/test_vivado_conformal_flow.py @@ -6,7 +6,8 @@ import unittest from bfasst.ninja_flows.flow_utils import create_build_file from bfasst.ninja_flows.vivado_conformal import VivadoConformal -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.compare.conformal.conformal import Conformal from bfasst.paths import ( @@ -50,7 +51,8 @@ def test_add_ninja_deps(self): self.flow.add_ninja_deps(observed) expected = ["foo", "bar"] Xray(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) - Vivado(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) Conformal(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) expected.append(NINJA_FLOWS_PATH / "vivado_conformal.py") observed = sorted([str(s) for s in observed]) diff --git a/test/flows/test_vivado_flow.py b/test/flows/test_vivado_flow.py index 6d0374493..ddc739066 100644 --- a/test/flows/test_vivado_flow.py +++ b/test/flows/test_vivado_flow.py @@ -8,7 +8,8 @@ from bfasst.ninja_flows.flow_utils import create_build_file from bfasst.ninja_flows.vivado import Vivado -from bfasst.ninja_tools.vivado.vivado import Vivado as VivadoTool +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -42,37 +43,41 @@ def test_rule_snippets_exist(self): def test_json_exist(self): # test that the json files for synth and impl templates exist - self.assertTrue((self.flow.vivado_tool.synth_output / "synth.json").exists()) - self.assertTrue((self.flow.vivado_tool.impl_output / "impl.json").exists()) + self.assertTrue((self.flow.vivado_synth_tool.build_path / "synth.json").exists()) + self.assertTrue((self.flow.vivado_impl_tool.build_path / "impl.json").exists()) def test_tcl_json_accurate(self): """Test that the json files for synth and impl templates are accurate.""" synth_dict = { - "part": self.flow.vivado_tool.part, - "verilog": self.flow.vivado_tool.verilog, - "system_verilog": self.flow.vivado_tool.system_verilog, + "part": self.flow.vivado_synth_tool.part, + "verilog": self.flow.vivado_synth_tool.verilog, + "system_verilog": self.flow.vivado_synth_tool.system_verilog, "vhdl": [], "vhdl_libs": [], - "top": self.flow.vivado_tool.top, - "io": str(self.flow.vivado_tool.synth_output / "report_io.txt"), - "synth_output": str(self.flow.vivado_tool.synth_output), + "top": self.flow.vivado_synth_tool.top, + "io": str(self.flow.vivado_synth_tool.build_path / "report_io.txt"), + "synth_output": str(self.flow.vivado_synth_tool.build_path), "flow_args": "", } expected_synth_json = json.dumps(synth_dict, indent=4) self.assertTrue( - compare_json(self.flow.vivado_tool.synth_output / "synth.json", expected_synth_json) + compare_json(self.flow.vivado_synth_tool.build_path / "synth.json", expected_synth_json) ) impl_dict = { - "part": self.flow.vivado_tool.part, - "xdc": str(self.flow.vivado_tool.synth_output / (self.flow.vivado_tool.top + ".xdc")), - "bit": str(self.flow.vivado_tool.impl_output / (self.flow.vivado_tool.top + ".bit")), - "impl_output": str(self.flow.vivado_tool.impl_output), - "synth_output": str(self.flow.vivado_tool.synth_output), + "part": self.flow.vivado_synth_tool.part, + "xdc": str( + self.flow.vivado_synth_tool.build_path / (self.flow.vivado_synth_tool.top + ".xdc") + ), + "bit": str( + self.flow.vivado_impl_tool.build_path / (self.flow.vivado_synth_tool.top + ".bit") + ), + "impl_output": str(self.flow.vivado_impl_tool.build_path), + "synth_output": str(self.flow.vivado_synth_tool.build_path), } expected_impl_json = json.dumps(impl_dict, indent=4) self.assertTrue( - compare_json(self.flow.vivado_tool.impl_output / "impl.json", expected_impl_json) + compare_json(self.flow.vivado_impl_tool.build_path / "impl.json", expected_impl_json) ) def test_build_snippets_exist(self): @@ -90,7 +95,8 @@ def test_add_ninja_deps(self): "foo", "bar", ] - VivadoTool(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) expected.append(NINJA_FLOWS_PATH / "vivado.py") self.assertEqual(observed, expected) diff --git a/test/flows/test_vivado_ooc_flow.py b/test/flows/test_vivado_ooc_flow.py index 81cb3b2d5..10205cb51 100644 --- a/test/flows/test_vivado_ooc_flow.py +++ b/test/flows/test_vivado_ooc_flow.py @@ -2,7 +2,8 @@ import json import unittest from bfasst.ninja_flows.vivado_ooc import VivadoOoc -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -38,31 +39,31 @@ def test_rule_snippets_exist(self): def test_tcl_json_accurate(self): """Test that the json file used to template the tcl file is accurate""" synth_dict = { - "part": self.flow.vivado_tool.part, - "verilog": self.flow.vivado_tool.verilog, - "system_verilog": self.flow.vivado_tool.system_verilog, + "part": self.flow.vivado_synth_tool.part, + "verilog": self.flow.vivado_synth_tool.verilog, + "system_verilog": self.flow.vivado_synth_tool.system_verilog, "vhdl": [], "vhdl_libs": [], - "top": self.flow.vivado_tool.top, + "top": self.flow.vivado_synth_tool.top, "io": False, - "synth_output": str(self.flow.vivado_tool.synth_output), + "synth_output": str(self.flow.vivado_synth_tool.build_path), "flow_args": "", } expected_synth_json = json.dumps(synth_dict, indent=4) self.assertTrue( - compare_json(self.flow.vivado_tool.synth_output / "synth.json", expected_synth_json) + compare_json(self.flow.vivado_synth_tool.build_path / "synth.json", expected_synth_json) ) impl_dict = { - "part": self.flow.vivado_tool.part, + "part": self.flow.vivado_synth_tool.part, "xdc": False, "bit": False, - "impl_output": str(self.flow.vivado_tool.impl_output), - "synth_output": str(self.flow.vivado_tool.synth_output), + "impl_output": str(self.flow.vivado_impl_tool.build_path), + "synth_output": str(self.flow.vivado_synth_tool.build_path), } expected_impl_json = json.dumps(impl_dict, indent=4) self.assertTrue( - compare_json(self.flow.vivado_tool.impl_output / "impl.json", expected_impl_json) + compare_json(self.flow.vivado_impl_tool.build_path / "impl.json", expected_impl_json) ) def test_build_snippets_exist(self): @@ -80,7 +81,8 @@ def test_add_ninja_deps(self): "foo", "bar", ] - Vivado(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) expected.append(NINJA_FLOWS_PATH / "vivado_ooc.py") expected.append(NINJA_FLOWS_PATH / "vivado.py") diff --git a/test/flows/test_vivado_phys_netlist.py b/test/flows/test_vivado_phys_netlist.py index 4daaec206..1b033bc6b 100644 --- a/test/flows/test_vivado_phys_netlist.py +++ b/test/flows/test_vivado_phys_netlist.py @@ -8,7 +8,8 @@ from bfasst.ninja_flows.flow_utils import create_build_file from bfasst.ninja_flows.vivado_phys_netlist import VivadoPhysNetlist from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -54,7 +55,8 @@ def test_add_ninja_deps(self): "foo", "bar", ] - Vivado(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) PhysNetlist(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) expected.append(NINJA_FLOWS_PATH / "vivado_phys_netlist.py") diff --git a/test/flows/test_vivado_phys_netlist_cmp_flow.py b/test/flows/test_vivado_phys_netlist_cmp_flow.py index 27f4ba8b9..73432353f 100644 --- a/test/flows/test_vivado_phys_netlist_cmp_flow.py +++ b/test/flows/test_vivado_phys_netlist_cmp_flow.py @@ -10,7 +10,8 @@ from bfasst.ninja_tools.compare.structural.structural import Structural from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -58,7 +59,8 @@ def test_add_ninja_deps(self): "foo", "bar", ] - Vivado(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) PhysNetlist(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) Xray(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) Structural(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) diff --git a/test/flows/test_vivado_phys_netlist_xrev_flow.py b/test/flows/test_vivado_phys_netlist_xrev_flow.py index 00fdbca1e..2a4e6d608 100644 --- a/test/flows/test_vivado_phys_netlist_xrev_flow.py +++ b/test/flows/test_vivado_phys_netlist_xrev_flow.py @@ -9,7 +9,8 @@ from bfasst.ninja_flows.vivado_phys_netlist_xrev import VivadoPhysNetlistXrev from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -56,7 +57,8 @@ def test_add_ninja_deps(self): "foo", "bar", ] - Vivado(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) PhysNetlist(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) Xray(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) expected.append(NINJA_FLOWS_PATH / "vivado_phys_netlist_xrev.py") diff --git a/test/flows/test_vivado_structural_error_injection_flow.py b/test/flows/test_vivado_structural_error_injection_flow.py index 37ff35588..0905eaf92 100644 --- a/test/flows/test_vivado_structural_error_injection_flow.py +++ b/test/flows/test_vivado_structural_error_injection_flow.py @@ -11,7 +11,8 @@ from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.transform.error_injector import ErrorInjector from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -61,7 +62,8 @@ def test_add_ninja_deps(self): "bar", ] desing_path = DESIGNS_PATH / "byu/alu" - Vivado(desing_path).add_ninja_deps(expected) + VivadoSynth(desing_path).add_ninja_deps(expected) + VivadoImpl(desing_path).add_ninja_deps(expected) ErrorInjector(desing_path).add_ninja_deps(expected) PhysNetlist(desing_path).add_ninja_deps(expected) Xray(desing_path).add_ninja_deps(expected) diff --git a/test/flows/test_vivado_yosys_impl_flow.py b/test/flows/test_vivado_yosys_impl_flow.py index 57cb78116..9c4f8f107 100644 --- a/test/flows/test_vivado_yosys_impl_flow.py +++ b/test/flows/test_vivado_yosys_impl_flow.py @@ -9,7 +9,8 @@ from bfasst.ninja_flows.vivado_yosys_impl import VivadoYosysImpl from bfasst.ninja_tools.compare.yosys.yosys import Yosys from bfasst.ninja_tools.rev_bit.xray import Xray -from bfasst.ninja_tools.vivado.vivado import Vivado +from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth +from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import DESIGNS_PATH, NINJA_BUILD_PATH, NINJA_FLOWS_PATH @@ -48,7 +49,8 @@ def test_add_ninja_deps(self): self.flow.add_ninja_deps(observed) expected = ["foo", "bar"] Xray(self.design_shortname).add_ninja_deps(expected) - Vivado(self.design_shortname).add_ninja_deps(expected) + VivadoSynth(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) + VivadoImpl(DESIGNS_PATH / "byu/alu").add_ninja_deps(expected) Yosys(self.design_shortname).add_ninja_deps(expected) expected.append(NINJA_FLOWS_PATH / "vivado_yosys_impl.py") # observed.sort() From 80c17f4395f34f6374c06c2a583333dd1b9ebb80 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Mon, 6 Nov 2023 14:51:00 -0700 Subject: [PATCH 5/7] refactored so build directories are created correctly on start of flow --- bfasst/ninja_tools/vivado/impl/vivado_impl.py | 3 ++- bfasst/ninja_tools/vivado/synth/vivado_synth.py | 1 + bfasst/ninja_tools/vivado/vivado.py | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/bfasst/ninja_tools/vivado/impl/vivado_impl.py b/bfasst/ninja_tools/vivado/impl/vivado_impl.py index 84414c7b7..f8da8c297 100644 --- a/bfasst/ninja_tools/vivado/impl/vivado_impl.py +++ b/bfasst/ninja_tools/vivado/impl/vivado_impl.py @@ -13,7 +13,8 @@ class VivadoImpl(Vivado): def __init__(self, design, ooc=False): super().__init__(design, ooc) - self.build_path = self.design_build_path / "impl" + self.build_path = self.build_path / "impl" + self._create_build_dir() # outputs must be initialized AFTER output paths are set self._init_outputs() diff --git a/bfasst/ninja_tools/vivado/synth/vivado_synth.py b/bfasst/ninja_tools/vivado/synth/vivado_synth.py index a7c4116a8..3e6dd32b9 100644 --- a/bfasst/ninja_tools/vivado/synth/vivado_synth.py +++ b/bfasst/ninja_tools/vivado/synth/vivado_synth.py @@ -13,6 +13,7 @@ def __init__(self, design, flow_args=None, ooc=False): self.flow_args = flow_args self.build_path = self.build_path / "synth" + self._create_build_dir() # outputs must be initialized AFTER output paths are set self._init_outputs() diff --git a/bfasst/ninja_tools/vivado/vivado.py b/bfasst/ninja_tools/vivado/vivado.py index e99b3509d..0bd10e2a6 100644 --- a/bfasst/ninja_tools/vivado/vivado.py +++ b/bfasst/ninja_tools/vivado/vivado.py @@ -65,8 +65,8 @@ def create_rule_snippets(self): Vivado.rules_appended_to_build = True def create_build_snippets(self): - self.__write_json_file() - self.__append_build_snippets() + self._write_json_file() + self._append_build_snippets() def _json_write(self, old_path, new_string): """Write the json file for the tool, if the new string @@ -77,10 +77,10 @@ def _json_write(self, old_path, new_string): with open(old_path, "w") as f: f.write(new_string) - def __write_json_file(self): + def _write_json_file(self): pass - def __append_build_snippets(self): + def _append_build_snippets(self): pass def add_ninja_deps(self): From 9df4579c26b056c3e506d6ffb28e1064a506f581 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Mon, 6 Nov 2023 16:39:57 -0700 Subject: [PATCH 6/7] fixed bug where vivado unit tests were failing by making sure static variable allowing rules to be written was reset correctly after each test --- test/flows/test_vivado_bit_analysis_flow.py | 5 +++++ test/flows/test_vivado_conformal_flow.py | 5 +++++ test/flows/test_vivado_flow.py | 5 +++++ test/flows/test_vivado_ooc_flow.py | 5 +++++ test/flows/test_vivado_phys_netlist.py | 5 +++++ test/flows/test_vivado_phys_netlist_cmp_flow.py | 5 +++++ test/flows/test_vivado_phys_netlist_xrev_flow.py | 5 +++++ test/flows/test_vivado_structural_error_injection_flow.py | 5 +++++ test/flows/test_vivado_yosys_impl_flow.py | 5 +++++ 9 files changed, 45 insertions(+) diff --git a/test/flows/test_vivado_bit_analysis_flow.py b/test/flows/test_vivado_bit_analysis_flow.py index fe6ed6a62..214b5b7ff 100644 --- a/test/flows/test_vivado_bit_analysis_flow.py +++ b/test/flows/test_vivado_bit_analysis_flow.py @@ -12,6 +12,7 @@ from bfasst.ninja_tools.transform.netlist_phys_to_logical import NetlistPhysToLogicalTool from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -27,6 +28,10 @@ def setUpClass(cls): # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoBitAnalysis(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_conformal_flow.py b/test/flows/test_vivado_conformal_flow.py index 9f6b03a8b..ac7c42826 100644 --- a/test/flows/test_vivado_conformal_flow.py +++ b/test/flows/test_vivado_conformal_flow.py @@ -10,6 +10,7 @@ from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.compare.conformal.conformal import Conformal +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -25,6 +26,10 @@ def setUpClass(cls) -> None: # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoConformal(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_flow.py b/test/flows/test_vivado_flow.py index ddc739066..18ec7e3a7 100644 --- a/test/flows/test_vivado_flow.py +++ b/test/flows/test_vivado_flow.py @@ -8,6 +8,7 @@ from bfasst.ninja_flows.flow_utils import create_build_file from bfasst.ninja_flows.vivado import Vivado +from bfasst.ninja_tools.vivado.vivado import Vivado as VivadoTool from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl from bfasst.paths import ( @@ -26,6 +27,10 @@ def setUpClass(cls): # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + VivadoTool.rules_appended_to_build = False + cls.flow = Vivado(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_ooc_flow.py b/test/flows/test_vivado_ooc_flow.py index 10205cb51..402954465 100644 --- a/test/flows/test_vivado_ooc_flow.py +++ b/test/flows/test_vivado_ooc_flow.py @@ -4,6 +4,7 @@ from bfasst.ninja_flows.vivado_ooc import VivadoOoc from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -21,6 +22,10 @@ def setUpClass(cls): with open(NINJA_BUILD_PATH, "w") as f: f.write("") + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoOoc(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_phys_netlist.py b/test/flows/test_vivado_phys_netlist.py index 1b033bc6b..698f62fcc 100644 --- a/test/flows/test_vivado_phys_netlist.py +++ b/test/flows/test_vivado_phys_netlist.py @@ -10,6 +10,7 @@ from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -25,6 +26,10 @@ def setUpClass(cls): # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoPhysNetlist(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_phys_netlist_cmp_flow.py b/test/flows/test_vivado_phys_netlist_cmp_flow.py index 73432353f..9a719c8b6 100644 --- a/test/flows/test_vivado_phys_netlist_cmp_flow.py +++ b/test/flows/test_vivado_phys_netlist_cmp_flow.py @@ -12,6 +12,7 @@ from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -27,6 +28,10 @@ def setUpClass(cls): # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoPhysNetlistCmp(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_phys_netlist_xrev_flow.py b/test/flows/test_vivado_phys_netlist_xrev_flow.py index 2a4e6d608..fb7f7edd7 100644 --- a/test/flows/test_vivado_phys_netlist_xrev_flow.py +++ b/test/flows/test_vivado_phys_netlist_xrev_flow.py @@ -11,6 +11,7 @@ from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -26,6 +27,10 @@ def setUpClass(cls): # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoPhysNetlistXrev(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_structural_error_injection_flow.py b/test/flows/test_vivado_structural_error_injection_flow.py index 0905eaf92..4a1b671db 100644 --- a/test/flows/test_vivado_structural_error_injection_flow.py +++ b/test/flows/test_vivado_structural_error_injection_flow.py @@ -13,6 +13,7 @@ from bfasst.ninja_tools.transform.phys_netlist import PhysNetlist from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import ( DESIGNS_PATH, NINJA_BUILD_PATH, @@ -28,6 +29,10 @@ def setUpClass(cls): # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.flow = VivadoStructuralErrorInjection(DESIGNS_PATH / "byu/alu") cls.flow.create_rule_snippets() cls.flow.create_build_snippets() diff --git a/test/flows/test_vivado_yosys_impl_flow.py b/test/flows/test_vivado_yosys_impl_flow.py index 9c4f8f107..da314a2e4 100644 --- a/test/flows/test_vivado_yosys_impl_flow.py +++ b/test/flows/test_vivado_yosys_impl_flow.py @@ -11,6 +11,7 @@ from bfasst.ninja_tools.rev_bit.xray import Xray from bfasst.ninja_tools.vivado.synth.vivado_synth import VivadoSynth from bfasst.ninja_tools.vivado.impl.vivado_impl import VivadoImpl +from bfasst.ninja_tools.vivado.vivado import Vivado from bfasst.paths import DESIGNS_PATH, NINJA_BUILD_PATH, NINJA_FLOWS_PATH @@ -22,6 +23,10 @@ def setUpClass(cls) -> None: # overwrite the build file so it is not appended to incorrectly create_build_file() + # before all vivado based flows, make sure the Vivado parent class is + # allowed to create its rule snippets + Vivado.rules_appended_to_build = False + cls.design_shortname = DESIGNS_PATH / "byu/alu" cls.flow = VivadoYosysImpl(cls.design_shortname) cls.flow.create_rule_snippets() From 89e55dfca4bca2c385ce4da1ffcc10f5ea926654 Mon Sep 17 00:00:00 2001 From: KeenanRileyFaulkner Date: Mon, 6 Nov 2023 16:45:34 -0700 Subject: [PATCH 7/7] pylint ignore duplicate code warnings for flows' create build snippets methods --- bfasst/ninja_flows/vivado_phys_netlist.py | 2 ++ bfasst/ninja_flows/vivado_phys_netlist_cmp.py | 2 ++ test/flows/test_vivado_conformal_flow.py | 2 ++ test/flows/test_vivado_yosys_impl_flow.py | 2 ++ 4 files changed, 8 insertions(+) diff --git a/bfasst/ninja_flows/vivado_phys_netlist.py b/bfasst/ninja_flows/vivado_phys_netlist.py index 5a5172c20..32bdbddb4 100644 --- a/bfasst/ninja_flows/vivado_phys_netlist.py +++ b/bfasst/ninja_flows/vivado_phys_netlist.py @@ -21,12 +21,14 @@ def create_rule_snippets(self): self.phys_netlist_tool.create_rule_snippets() def create_build_snippets(self): + # pylint: disable=duplicate-code self.vivado_synth_tool.create_build_snippets() self.vivado_impl_tool.create_build_snippets() self.phys_netlist_tool.create_build_snippets( impl_dcp=self.vivado_impl_tool.outputs["impl_checkpoint"], impl_edf=self.vivado_impl_tool.outputs["impl_edf"], ) + # pylint: enable=duplicate-code def add_ninja_deps(self, deps): self.vivado_synth_tool.add_ninja_deps(deps) diff --git a/bfasst/ninja_flows/vivado_phys_netlist_cmp.py b/bfasst/ninja_flows/vivado_phys_netlist_cmp.py index 7959b55d4..d2d557d15 100644 --- a/bfasst/ninja_flows/vivado_phys_netlist_cmp.py +++ b/bfasst/ninja_flows/vivado_phys_netlist_cmp.py @@ -27,6 +27,7 @@ def create_rule_snippets(self): self.compare_tool.create_rule_snippets() def create_build_snippets(self): + # pylint: disable=duplicate-code self.vivado_synth_tool.create_build_snippets() self.vivado_impl_tool.create_build_snippets() self.phys_netlist_tool.create_build_snippets( @@ -39,6 +40,7 @@ def create_build_snippets(self): netlist_b=self.phys_netlist_tool.outputs["viv_impl_physical_v"], log_name="struct_cmp.log", ) + # pylint: enable=duplicate-code def add_ninja_deps(self, deps): self.vivado_synth_tool.add_ninja_deps(deps) diff --git a/test/flows/test_vivado_conformal_flow.py b/test/flows/test_vivado_conformal_flow.py index ac7c42826..69efb4e00 100644 --- a/test/flows/test_vivado_conformal_flow.py +++ b/test/flows/test_vivado_conformal_flow.py @@ -52,6 +52,8 @@ def test_build_snippets_exist(self): self.assertEqual(build_statement_count, 8) def test_add_ninja_deps(self): + """Test that the flow adds the correct dependencies to the ninja build file + for reconfiguration""" observed = ["foo", "bar"] self.flow.add_ninja_deps(observed) expected = ["foo", "bar"] diff --git a/test/flows/test_vivado_yosys_impl_flow.py b/test/flows/test_vivado_yosys_impl_flow.py index da314a2e4..eaab7e234 100644 --- a/test/flows/test_vivado_yosys_impl_flow.py +++ b/test/flows/test_vivado_yosys_impl_flow.py @@ -50,6 +50,8 @@ def test_build_snippets_exist(self): self.assertEqual(build_statement_count, 9) def test_add_ninja_deps(self): + """Test that the flow adds the correct dependencies to the ninja build file + for reconfiguration""" observed = ["foo", "bar"] self.flow.add_ninja_deps(observed) expected = ["foo", "bar"]