From c8b336957fb5f558b872ef1a568fd6964a14b433 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sat, 25 Jun 2022 15:22:30 +0200 Subject: [PATCH] build/generic_toolchain, soc/integration/builder: introducing a backend argument and edalize as alternate backend --- litex/build/generic_toolchain.py | 73 ++++++++++++++++++++++++++------ litex/soc/integration/builder.py | 6 +++ 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/litex/build/generic_toolchain.py b/litex/build/generic_toolchain.py index c1682b873..4e9ea247c 100644 --- a/litex/build/generic_toolchain.py +++ b/litex/build/generic_toolchain.py @@ -17,22 +17,23 @@ class GenericToolchain: "keep": ("keep", "true"), } + supported_backend = ["LiteX"] + def __init__(self): self.clocks = dict() self.false_paths = set() # FIXME: use it self.named_pc = [] self.named_sc = [] + self._synth_opts = "" def build_io_constraints(self): raise NotImplementedError("GenericToolchain.build_io_constraints must be overloaded.") def build_placement_constraints(self): - # FIXME: Switch to fixed parameter when determined? - pass # Pass since optional. + return ("","") # Empty since optional. def build_timing_constraints(self, vns): - # FIXME: Switch to fixed parameter when determined? - pass # Pass since optional. + return ("","") # Empty since optional. def build_project(self): pass # Pass since optional. @@ -40,15 +41,19 @@ class GenericToolchain: def build_script(self): raise NotImplementedError("GenericToolchain.build_script must be overloaded.") + def get_tool_options(self): + return ("",{}) # empty since optional. + def _build(self, platform, fragment, build_dir = "build", build_name = "top", synth_opts = "", run = True, + backend = "LiteX", **kwargs): self._build_name = build_name - self._synth_opts = synth_opts + self._synth_opts += synth_opts self.platform = platform # Create Build Directory. @@ -69,20 +74,60 @@ class GenericToolchain: platform.add_source(v_file) # Generate Design IO Constraints File. - self.build_io_constraints() + io_cst_file = self.build_io_constraints() # Generate Design Timing Constraints File. - self.build_timing_constraints(v_output.ns) + tim_cst_file = self.build_timing_constraints(v_output.ns) - # Generate project. - self.build_project() + if backend not in self.supported_backend: + raise NotImplementedError("Backend {backend} not supported by {toolchain} toolchain".format( + backend=backend, + toolchain=type(self).__name__)) + + if backend == "LiteX": + # Generate project. + self.build_project() + + # Generate build script. + script = self.build_script() + + # Run. + if run: + self.run_script(script) + else: + from edalize import get_edatool + + # Get tool name and options + (tool, tool_options)= self.get_tool_options() + + # Files list + files = [] + for filename, language, library, *copy in self.platform.sources: + ext = { + "verilog" : "verilogSource", + "systemverilog": "systemVerilogSource", + "vhdl" : "vhdlSource" + }[language] + files.append({'name': filename, 'file_type': ext}) + + # IO/timings constraints + files.append({'name':os.path.abspath(io_cst_file[0]), 'file_type':io_cst_file[1]}) + if tim_cst_file[0] != "": + files.append({'name':os.path.abspath(tim_cst_file[0]), 'file_type':tim_cst_file[1]}) + + edam = { + 'name' : self._build_name, + 'files' : files, + 'tool_options' : {tool: tool_options}, + 'toplevel' : self._build_name, + } + + backend = get_edatool(tool)(edam=edam, work_root=build_dir) + backend.configure() + if run: + backend.build() - # Generate build script. - script = self.build_script() - # Run. - if run: - self.run_script(script) os.chdir(cwd) diff --git a/litex/soc/integration/builder.py b/litex/soc/integration/builder.py index ee8e47ebb..ae907008c 100644 --- a/litex/soc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -72,6 +72,7 @@ class Builder: # Compile Options. compile_software = True, compile_gateware = True, + backend = "LiteX", # Exports. csr_json = None, @@ -97,6 +98,7 @@ class Builder: # Compile Options. self.compile_software = compile_software self.compile_gateware = compile_gateware + self.backend = backend # Exports. self.csr_csv = csr_csv @@ -346,6 +348,8 @@ class Builder: if "run" not in kwargs: kwargs["run"] = self.compile_gateware + kwargs["backend"] = self.backend + # Build SoC and pass Verilog Name Space to do_exit. vns = self.soc.build(build_dir=self.gateware_dir, **kwargs) self.soc.do_exit(vns=vns) @@ -389,6 +393,7 @@ def builder_args(parser): builder_group.add_argument("--csr-svd", default=None, help="Write SoC mapping to the specified SVD file.") builder_group.add_argument("--memory-x", default=None, help="Write SoC Memory Regions to the specified Memory-X file.") builder_group.add_argument("--doc", action="store_true", help="Generate SoC Documentation.") + builder_group.add_argument("--backend", default="LiteX", help="Select backend: LiteX, edalize.") def builder_argdict(args): @@ -405,4 +410,5 @@ def builder_argdict(args): "csr_svd": args.csr_svd, "memory_x": args.memory_x, "generate_doc": args.doc, + "backend": args.backend, }