From c0fa4fd1f442d14d8dbad2854157bb36f17d86e1 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Mon, 28 Sep 2020 13:12:07 +0200 Subject: [PATCH] initial build support for Gowin --- litex/build/gowin/__init__.py | 0 litex/build/gowin/common.py | 8 +++ litex/build/gowin/gowin.py | 113 ++++++++++++++++++++++++++++++++++ litex/build/gowin/platform.py | 34 ++++++++++ 4 files changed, 155 insertions(+) create mode 100644 litex/build/gowin/__init__.py create mode 100644 litex/build/gowin/common.py create mode 100644 litex/build/gowin/gowin.py create mode 100644 litex/build/gowin/platform.py diff --git a/litex/build/gowin/__init__.py b/litex/build/gowin/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/litex/build/gowin/common.py b/litex/build/gowin/common.py new file mode 100644 index 000000000..3d428dea3 --- /dev/null +++ b/litex/build/gowin/common.py @@ -0,0 +1,8 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2020 Pepijn de Vos +# Copyright (c) 2015-2018 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +gowin_special_overrides = {} diff --git a/litex/build/gowin/gowin.py b/litex/build/gowin/gowin.py new file mode 100644 index 000000000..26234a15c --- /dev/null +++ b/litex/build/gowin/gowin.py @@ -0,0 +1,113 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2020 Pepijn de Vos +# Copyright (c) 2015-2018 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +import os +import subprocess + +from migen.fhdl.structure import _Fragment + +from litex.build.generic_platform import Pins, IOStandard, Misc +from litex.build import tools + +def _build_cst(named_sc, named_pc): + lines = [] + + flat_sc = [] + for name, pins, other, resource in named_sc: + if len(pins) > 1: + for i, p in enumerate(pins): + flat_sc.append((f"{name}[{i}]", p, other)) + else: + flat_sc.append((name, pins[0], other)) + + for name, pin, other in flat_sc: + lines.append(f"IO_LOC \"{name}\" {pin};") + + for c in other: + if isinstance(c, IOStandard): + lines.append(f"IO_PORT \"{name}\" IO_TYPE={c.name};") + elif isinstance(c, Misc): + lines.append(f"IO_PORT \"{name}\" {c.misc};") + + if named_pc: + lines.extend(named_pc) + + cst = "\n".join(lines) + with open("top.cst", "w") as f: + f.write(cst) + +def _build_script(name, partnumber, files, options): + lines = [ + f"set_device -name {name} {partnumber}", + "add_file top.cst", + ] + + for f, typ, lib in files: + lines.append(f"add_file {f}") + + for opt, val in options.items(): + lines.append(f"set_option -{opt} {val}") + + lines.append("run all") + + tcl = "\n".join(lines) + with open("run.tcl", "w") as f: + f.write(tcl) + +class GowinToolchain(): + def __init__(self): + self.options = {} + + def attr_translate(*args): + print(args) + pass + + def build(self, platform, fragment, + build_dir = "build", + build_name = "top", + run = True, + **kwargs): + + # Create build directory + cwd = os.getcwd() + os.makedirs(build_dir, exist_ok=True) + os.chdir(build_dir) + + # Finalize design + if not isinstance(fragment, _Fragment): + fragment = fragment.get_fragment() + platform.finalize(fragment) + + # Generate verilog + 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) + platform.add_source(v_file) + + if platform.verilog_include_paths: + self.options['includ_path'] = '{' + ';'.join(platform.verilog_include_paths) + '}' + + # Generate constraints file (.cst) + _build_cst( + named_sc = named_sc, + named_pc = named_pc) + + # Generate TCL build script + script = _build_script( + name = platform.name, + partnumber = platform.device, + files = platform.sources, + options = self.options) + + # Run + if run: + subprocess.run(["gw_sh", "run.tcl"]) + + os.chdir(cwd) + + return v_output.ns diff --git a/litex/build/gowin/platform.py b/litex/build/gowin/platform.py new file mode 100644 index 000000000..82aabc5de --- /dev/null +++ b/litex/build/gowin/platform.py @@ -0,0 +1,34 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2020 Pepijn de Vos +# Copyright (c) 2015-2018 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +import os + +from litex.build.generic_platform import GenericPlatform +from litex.build.gowin import common, gowin + +# GowinPlatform ----------------------------------------------------------------------------------- + +class GowinPlatform(GenericPlatform): + bitstream_ext = ".fs" + + def __init__(self, *args, toolchain="gowin", **kwargs): + GenericPlatform.__init__(self, *args, **kwargs) + if toolchain == "gowin": + self.toolchain = gowin.GowinToolchain() + elif toolchain == "apicula": + raise ValueError("Apicula toolchain needs more work") + else: + raise ValueError("Unknown toolchain") + + def get_verilog(self, *args, special_overrides=dict(), **kwargs): + so = dict(common.gowin_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)