mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
initial build support for Gowin
This commit is contained in:
parent
a1c023b900
commit
c0fa4fd1f4
4 changed files with 155 additions and 0 deletions
0
litex/build/gowin/__init__.py
Normal file
0
litex/build/gowin/__init__.py
Normal file
8
litex/build/gowin/common.py
Normal file
8
litex/build/gowin/common.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteX.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Pepijn de Vos <pepijndevos@gmail.com>
|
||||||
|
# Copyright (c) 2015-2018 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
gowin_special_overrides = {}
|
113
litex/build/gowin/gowin.py
Normal file
113
litex/build/gowin/gowin.py
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteX.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Pepijn de Vos <pepijndevos@gmail.com>
|
||||||
|
# Copyright (c) 2015-2018 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# 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
|
34
litex/build/gowin/platform.py
Normal file
34
litex/build/gowin/platform.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteX.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Pepijn de Vos <pepijndevos@gmail.com>
|
||||||
|
# Copyright (c) 2015-2018 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# 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)
|
Loading…
Reference in a new issue