From 60edca234509b0078e7b953b64e4c407eb5ecd52 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 6 Dec 2019 11:14:57 +0100 Subject: [PATCH] build/microsemi: cleanup/simplify (no functional change) --- litex/build/microsemi/common.py | 4 +- litex/build/microsemi/libero_soc.py | 105 +++++++++++++++------------- litex/build/microsemi/platform.py | 3 +- 3 files changed, 63 insertions(+), 49 deletions(-) diff --git a/litex/build/microsemi/common.py b/litex/build/microsemi/common.py index 55ff8f09..7e7a309e 100644 --- a/litex/build/microsemi/common.py +++ b/litex/build/microsemi/common.py @@ -1,9 +1,10 @@ -# This file is Copyright (c) 2018 Florent Kermarrec +# This file is Copyright (c) 2018-2019 Florent Kermarrec # License: BSD from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer +# AsyncResetSynchronizer --------------------------------------------------------------------------- class MicrosemiPolarfireAsyncResetSynchronizerImpl(Module): def __init__(self, cd, async_reset): @@ -25,6 +26,7 @@ class MicrosemiPolarfireAsyncResetSynchronizer: def lower(dr): return MicrosemiPolarfireAsyncResetSynchronizerImpl(dr.cd, dr.async_reset) +# Special Overrides -------------------------------------------------------------------------------- microsemi_polarfire_special_overrides = { AsyncResetSynchronizer: MicrosemiPolarfireAsyncResetSynchronizer, diff --git a/litex/build/microsemi/libero_soc.py b/litex/build/microsemi/libero_soc.py index f827d154..7ca51db3 100644 --- a/litex/build/microsemi/libero_soc.py +++ b/litex/build/microsemi/libero_soc.py @@ -1,4 +1,4 @@ -# This file is Copyright (c) 2018 Florent Kermarrec +# This file is Copyright (c) 2018-2019 Florent Kermarrec # License: BSD import os @@ -13,9 +13,12 @@ from litex.build import tools from litex.build.microsemi import common +# Helpers ------------------------------------------------------------------------------------------ + def tcl_name(name): return "{" + name + "}" +# IO Constraints (.pdc) ---------------------------------------------------------------------------- def _format_io_constraint(c): if isinstance(c, Pins): @@ -38,7 +41,6 @@ def _format_io_pdc(signame, pin, others): r += "\n" return r - def _build_io_pdc(named_sc, named_pc, build_name, additional_io_constraints): pdc = "" for sig, pins, others, resname in named_sc: @@ -50,16 +52,18 @@ def _build_io_pdc(named_sc, named_pc, build_name, additional_io_constraints): pdc += "\n".join(additional_io_constraints) tools.write_to_file(build_name + "_io.pdc", pdc) +# Placement Constraints (.pdc) --------------------------------------------------------------------- def _build_fp_pdc(build_name, additional_fp_constraints): pdc = "\n".join(additional_fp_constraints) tools.write_to_file(build_name + "_fp.pdc", pdc) +# Project (.tcl) ----------------------------------------------------------------------------------- def _build_tcl(platform, sources, build_dir, build_name): tcl = [] - # create project + # Create project tcl.append(" ".join([ "new_project", "-location {./impl}", @@ -103,29 +107,29 @@ def _build_tcl(platform, sources, build_dir, build_name): "-adv_options {VOLTR:EXT} " ])) - # add files + # Add sources for filename, language, library in sources: filename_tcl = "{" + filename + "}" tcl.append("import_files -hdl_source " + filename_tcl) - # set top + # Set top level tcl.append("set_root -module {}".format(tcl_name(build_name))) - # copy init files FIXME: support for include path on LiberoSoC? + # Copy init files FIXME: support for include path on LiberoSoC? for file in os.listdir(build_dir): if file.endswith(".init"): tcl.append("file copy -- {} impl/synthesis".format(file)) - # import io constraints + # Import io constraints tcl.append("import_files -io_pdc {}".format(tcl_name(build_name + "_io.pdc"))) - # import floorplanner constraints + # Import floorplanner constraints tcl.append("import_files -fp_pdc {}".format(tcl_name(build_name + "_fp.pdc"))) - # import timing constraints + # Import timing constraints tcl.append("import_files -convert_EDN_to_HDL 0 -sdc {}".format(tcl_name(build_name + ".sdc"))) - # associate constraints with tools + # Associate constraints with tools tcl.append(" ".join(["organize_tool_files", "-tool {SYNTHESIZE}", "-file impl/constraint/{}.sdc".format(build_name), @@ -147,16 +151,17 @@ def _build_tcl(platform, sources, build_dir, build_name): "-input_type {constraint}" ])) - # build flow + # Build flow tcl.append("run_tool -name {CONSTRAINT_MANAGEMENT}") tcl.append("run_tool -name {SYNTHESIZE}") tcl.append("run_tool -name {PLACEROUTE}") tcl.append("run_tool -name {GENERATEPROGRAMMINGDATA}") tcl.append("run_tool -name {GENERATEPROGRAMMINGFILE}") - # generate tcl + # Generate tcl tools.write_to_file(build_name + ".tcl", "\n".join(tcl)) +# Timing Constraints (.sdc) ------------------------------------------------------------------------ def _build_timing_sdc(vns, clocks, false_paths, build_name, additional_timing_constraints): sdc = [] @@ -177,27 +182,27 @@ def _build_timing_sdc(vns, clocks, false_paths, build_name, additional_timing_co sdc += additional_timing_constraints tools.write_to_file(build_name + ".sdc", "\n".join(sdc)) +# Script ------------------------------------------------------------------------------------------- def _build_script(build_name, device, toolchain_path, ver=None): if sys.platform in ("win32", "cygwin"): script_ext = ".bat" - build_script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n" + script_contents = "@echo off\nREM Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n" copy_stmt = "copy" fail_stmt = " || exit /b" else: script_ext = ".sh" - build_script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n" + script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n" copy_stmt = "cp" fail_stmt = " || exit 1" - build_script_file = "build_" + build_name + script_ext - tools.write_to_file(build_script_file, build_script_contents, + script_file = "build_" + build_name + script_ext + tools.write_to_file(script_file, script_contents, force_unix=False) - return build_script_file - + return script_file def _run_script(script): - if sys.platform in ("win32", "cygwin"): + if sys.platform in ["win32", "cygwin"]: shell = ["cmd", "/c"] else: shell = ["bash"] @@ -205,75 +210,81 @@ def _run_script(script): if subprocess.call(shell + [script]) != 0: raise OSError("Subprocess failed") +# MicrosemiLiberoSoCPolarfireToolchain ------------------------------------------------------------- class MicrosemiLiberoSoCPolarfireToolchain: attr_translate = { # FIXME: document - "keep": None, - "no_retiming": None, - "async_reg": None, - "mr_ff": None, - "mr_false_path": None, - "ars_ff1": None, - "ars_ff2": None, - "ars_false_path": None, + "keep": None, + "no_retiming": None, + "async_reg": None, + "mr_ff": None, + "mr_false_path": None, + "ars_ff1": None, + "ars_ff2": None, + "ars_false_path": None, "no_shreg_extract": None } special_overrides = common.microsemi_polarfire_special_overrides def __init__(self): - self.clocks = dict() + self.clocks = dict() self.false_paths = set() - self.additional_io_constraints = [] - self.additional_fp_constraints = [] + self.additional_io_constraints = [] + self.additional_fp_constraints = [] self.additional_timing_constraints = [] - def build(self, platform, fragment, build_dir="build", build_name="top", - toolchain_path=None, run=False, **kwargs): - # create build directory + def build(self, platform, fragment, + build_dir = "build", + build_name = "top", + toolchain_path = None, + run = False, + **kwargs): + + # Create build directory os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) - # finalize design + # Finalize design if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) - # generate top module - top_output = platform.get_verilog(fragment, name=build_name, **kwargs) - named_sc, named_pc = platform.resolve_signals(top_output.ns) + # Generate verilog + v_output = platform.get_verilog(fragment, name=build_name, **kwargs) + named_sc, named_pc = platform.resolve_signals(v_output.ns) top_file = build_name + ".v" - top_output.write(top_file) + v_output.write(top_file) platform.add_source(top_file) - # generate design script file (.tcl) + # Generate design script file (.tcl) _build_tcl(platform, platform.sources, build_dir, build_name) - # generate design io constraints file (.pdc) + # Generate design io constraints file (.pdc) _build_io_pdc(named_sc, named_pc, build_name, self.additional_io_constraints) - # generate design fp constraints file (.pdc) + # Generate design placement constraints file (.pdc) _build_fp_pdc(build_name, self.additional_fp_constraints) - # generate design timing constraints file (sdc) - _build_timing_sdc(top_output.ns, self.clocks, self.false_paths, build_name, + # Generate design timing constraints file (.sdc) + _build_timing_sdc(v_output.ns, self.clocks, self.false_paths, build_name, self.additional_timing_constraints) - # generate build script + # Generate build script script = _build_script(build_name, platform.device, toolchain_path) - # run + # Run if run: - # delete previous impl + # Delete previous impl if os.path.exists("impl"): shutil.rmtree("impl") _run_script(script) os.chdir(cwd) - return top_output.ns + return v_output.ns def add_period_constraint(self, platform, clk, period): if clk in self.clocks: diff --git a/litex/build/microsemi/platform.py b/litex/build/microsemi/platform.py index 37a1762e..3f7a1396 100644 --- a/litex/build/microsemi/platform.py +++ b/litex/build/microsemi/platform.py @@ -1,9 +1,10 @@ -# This file is Copyright (c) 2018 Florent Kermarrec +# This file is Copyright (c) 2018-2019 Florent Kermarrec # License: BSD from litex.build.generic_platform import GenericPlatform from litex.build.microsemi import common, libero_soc +# MicrosemiPlatform -------------------------------------------------------------------------------- class MicrosemiPlatform(GenericPlatform): bitstream_ext = ".bit" -- 2.30.2