From 4cb6583b4ec92e600815fa1bbed27b71320699b2 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 15 Nov 2018 18:21:41 +0100 Subject: [PATCH] build: add microsemi template for polarfire fpgas support --- litex/boards/platforms/avalanche.py | 11 ++++ litex/build/microsemi/__init__.py | 1 + litex/build/microsemi/common.py | 2 + litex/build/microsemi/libero_soc.py | 84 +++++++++++++++++++++++++++++ litex/build/microsemi/platform.py | 29 ++++++++++ 5 files changed, 127 insertions(+) create mode 100644 litex/build/microsemi/__init__.py create mode 100644 litex/build/microsemi/common.py create mode 100644 litex/build/microsemi/libero_soc.py create mode 100644 litex/build/microsemi/platform.py diff --git a/litex/boards/platforms/avalanche.py b/litex/boards/platforms/avalanche.py index 4da58a247..e7f955a65 100644 --- a/litex/boards/platforms/avalanche.py +++ b/litex/boards/platforms/avalanche.py @@ -1,4 +1,8 @@ +# This file is Copyright (c) 2018 Florent Kermarrec +# License: BSD + from litex.build.generic_platform import * +from litex.build.microsemi import MicrosemiPlatform _io = [ ("clk50", 0, Pins("R1"), IOStandard("LVCMOS25")), @@ -76,3 +80,10 @@ _io = [ IOStandard("LVCMOS25") ), ] + +class Platform(MicrosemiPlatform): + default_clk_name = "clk50" + default_clk_period = 20.0 + + def __init__(self): + MicrosemiPlatform.__init__(self, "MPF300TS_ES", _io) diff --git a/litex/build/microsemi/__init__.py b/litex/build/microsemi/__init__.py new file mode 100644 index 000000000..1b054bb71 --- /dev/null +++ b/litex/build/microsemi/__init__.py @@ -0,0 +1 @@ +from litex.build.microsemi.platform import MicrosemiPlatform diff --git a/litex/build/microsemi/common.py b/litex/build/microsemi/common.py new file mode 100644 index 000000000..2b82aed3a --- /dev/null +++ b/litex/build/microsemi/common.py @@ -0,0 +1,2 @@ +microsemi_polarfire_special_overrides = { +} diff --git a/litex/build/microsemi/libero_soc.py b/litex/build/microsemi/libero_soc.py new file mode 100644 index 000000000..ff0043c8e --- /dev/null +++ b/litex/build/microsemi/libero_soc.py @@ -0,0 +1,84 @@ +# This file is Copyright (c) 2018 Florent Kermarrec +# License: BSD + +import os +import sys +import subprocess +import shutil + +from migen.fhdl.structure import _Fragment + +from litex.build.generic_platform import * +from litex.build import tools +from litex.build.microsemi import common + +def _build_files(device, sources, vincpaths, build_name): + print("TODO: _build_files") + +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 Migen\n\n" + copy_stmt = "copy" + fail_stmt = " || exit /b" + else: + raise NotImplementedError + + build_script_file = "build_" + build_name + script_ext + tools.write_to_file(build_script_file, build_script_contents, + force_unix=False) + return build_script_file + +def _run_script(script): + if sys.platform in ("win32", "cygwin"): + shell = ["cmd", "/c"] + else: + shell = ["bash"] + + if subprocess.call(shell + [script]) != 0: + raise OSError("Subprocess failed") + + +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, + "no_shreg_extract": None + } + + special_overrides = common.microsemi_polarfire_special_overrides + + def build(self, platform, fragment, build_dir="build", build_name="top", + toolchain_path=None, run=True, **kwargs): + os.makedirs(build_dir, exist_ok=True) + cwd = os.getcwd() + os.chdir(build_dir) + + if not isinstance(fragment, _Fragment): + fragment = fragment.get_fragment() + platform.finalize(fragment) + + v_output = platform.get_verilog(fragment, name=build_name, **kwargs) + named_sc, named_pc = platform.resolve_signals(v_output.ns) + v_file = build_name + ".v" + v_output.write(v_file) + sources = platform.sources | {(v_file, "verilog", "work")} + _build_files(platform.device, sources, platform.verilog_include_paths, build_name) + + script = _build_script(build_name, platform.device, toolchain_path) + if run: + _run_script(script) + + os.chdir(cwd) + + return v_output.ns + + def add_period_constraint(self, platform, clk, period): + print("TODO: add_period_constraint") \ No newline at end of file diff --git a/litex/build/microsemi/platform.py b/litex/build/microsemi/platform.py new file mode 100644 index 000000000..6ecb8e923 --- /dev/null +++ b/litex/build/microsemi/platform.py @@ -0,0 +1,29 @@ +from litex.build.generic_platform import GenericPlatform +from litex.build.microsemi import common, libero_soc + + +class MicrosemiPlatform(GenericPlatform): + bitstream_ext = ".bit" + + def __init__(self, *args, toolchain="libero_soc_polarfire", **kwargs): + GenericPlatform.__init__(self, *args, **kwargs) + if toolchain == "libero_soc_polarfire": + self.toolchain = libero_soc.MicrosemiLiberoSoCPolarfireToolchain() + else: + raise ValueError("Unknown toolchain") + + def get_verilog(self, *args, special_overrides=dict(), **kwargs): + so = dict() # No common overrides between ECP and ice40. + so.update(self.toolchain.special_overrides) + so.update(special_overrides) + return GenericPlatform.get_verilog(self, *args, special_overrides=so, + attr_translate=self.toolchain.attr_translate, + **kwargs) + + def build(self, *args, **kwargs): + return self.toolchain.build(self, *args, **kwargs) + + def add_period_constraint(self, clk, period): + if hasattr(clk, "p"): + clk = clk.p + self.toolchain.add_period_constraint(self, clk, period)