initial commit
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
commit
68694294e1
33
.gitmodules
vendored
Normal file
33
.gitmodules
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
[submodule "deps/migen"]
|
||||
path = deps/migen
|
||||
url = https://github.com/m-labs/migen.git
|
||||
[submodule "deps/litex"]
|
||||
path = deps/litex
|
||||
url = https://github.com/enjoy-digital/litex.git
|
||||
[submodule "deps/litescope"]
|
||||
path = deps/litescope
|
||||
url = https://github.com/enjoy-digital/litescope.git
|
||||
[submodule "deps/pyserial"]
|
||||
path = deps/pyserial
|
||||
url = https://github.com/pyserial/pyserial.git
|
||||
[submodule "deps/liteeth"]
|
||||
path = deps/liteeth
|
||||
url = https://github.com/enjoy-digital/liteeth.git
|
||||
[submodule "deps/liteusb"]
|
||||
path = deps/liteusb
|
||||
url = https://github.com/enjoy-digital/liteusb.git
|
||||
[submodule "deps/litedram"]
|
||||
path = deps/litedram
|
||||
url = https://github.com/enjoy-digital/litedram.git
|
||||
[submodule "deps/litepcie"]
|
||||
path = deps/litepcie
|
||||
url = https://github.com/enjoy-digital/litepcie.git
|
||||
[submodule "deps/litesdcard"]
|
||||
path = deps/litesdcard
|
||||
url = https://github.com/enjoy-digital/litesdcard.git
|
||||
[submodule "deps/liteiclink"]
|
||||
path = deps/liteiclink
|
||||
url = https://github.com/enjoy-digital/liteiclink.git
|
||||
[submodule "deps/litevideo"]
|
||||
path = deps/litevideo
|
||||
url = https://github.com/enjoy-digital/litevideo.git
|
14
bin/litex_read_verilog
Executable file
14
bin/litex_read_verilog
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
from litex.utils.litex_read_verilog import main
|
||||
main()
|
14
bin/litex_server
Executable file
14
bin/litex_server
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
from litex.utils.litex_server import main
|
||||
main()
|
14
bin/litex_sim
Executable file
14
bin/litex_sim
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
from litex.utils.litex_sim import main
|
||||
main()
|
14
bin/litex_simple
Executable file
14
bin/litex_simple
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
from litex.boards.targets.simple import main
|
||||
main()
|
14
bin/litex_term
Executable file
14
bin/litex_term
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
from litex.utils.litex_term import main
|
||||
main()
|
14
bin/mkmscimg
Executable file
14
bin/mkmscimg
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
from litex.soc.tools.mkmscimg import main
|
||||
main()
|
1
deps/litedram
vendored
Submodule
1
deps/litedram
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit fd3e9afbcd0872b645badc9b75aacab6dbf7459e
|
1
deps/liteeth
vendored
Submodule
1
deps/liteeth
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 77fa4bfb1e452adb1fa34c1b0baede68c056763d
|
1
deps/liteiclink
vendored
Submodule
1
deps/liteiclink
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ee9ae87641d98a1b9ad88e28042394797bfb9e00
|
1
deps/litepcie
vendored
Submodule
1
deps/litepcie
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 3804c4947adedc6c720e3041e518627b0bf57f78
|
1
deps/litescope
vendored
Submodule
1
deps/litescope
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c1d8bdf6f23b1070b8bd2dd277a4708863474148
|
1
deps/litesdcard
vendored
Submodule
1
deps/litesdcard
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c07165ff9f9e368c8147158b88fe90cea683e51c
|
1
deps/liteusb
vendored
Submodule
1
deps/liteusb
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0a9110f901182a1233cc4e64b6e39175f6784621
|
1
deps/litevideo
vendored
Submodule
1
deps/litevideo
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 98e145fba8c25394e9958bad67e2a457d145127e
|
1
deps/litex
vendored
Submodule
1
deps/litex
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ff155a474d12b62fb84db0ca07d2577687c5c141
|
1
deps/migen
vendored
Submodule
1
deps/migen
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit afe4405becdbc76539f0195c319367187012b05e
|
1
deps/pyserial
vendored
Submodule
1
deps/pyserial
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit a4d8f27bf636ee598c4368d7e488f78a226bf778
|
60
foboot-bitstream.py
Normal file
60
foboot-bitstream.py
Normal file
@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
# This variable defines all the external programs that this module
|
||||
# relies on. lxbuildenv reads this variable in order to ensure
|
||||
# the build will finish without exiting due to missing third-party
|
||||
# programs.
|
||||
LX_DEPENDENCIES = ["riscv", "icestorm", "yosys"]
|
||||
|
||||
# Import lxbuildenv to integrate the deps/ directory
|
||||
import lxbuildenv
|
||||
|
||||
# Disable pylint's E1101, which breaks completely on migen
|
||||
#pylint:disable=E1101
|
||||
|
||||
#from migen import *
|
||||
from litex.build.xilinx import VivadoProgrammer, XilinxPlatform
|
||||
from litex.build.generic_platform import Pins, IOStandard
|
||||
from litex.soc.integration import SoCSDRAM
|
||||
from litex.soc.integration.builder import Builder
|
||||
from litex.soc.integration.soc_core import csr_map_update
|
||||
|
||||
_io = [
|
||||
("clk50", 0, Pins("J19"), IOStandard("LVCMOS33")),
|
||||
]
|
||||
|
||||
class Platform(XilinxPlatform):
|
||||
def __init__(self, toolchain="vivado", programmer="vivado", part="35"):
|
||||
part = "xc7a" + part + "t-fgg484-2"
|
||||
def create_programmer(self):
|
||||
if self.programmer == "vivado":
|
||||
return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4")
|
||||
else:
|
||||
raise ValueError("{} programmer is not supported"
|
||||
.format(self.programmer))
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
|
||||
class BaseSoC(SoCSDRAM):
|
||||
csr_peripherals = [
|
||||
"ddrphy",
|
||||
# "dna",
|
||||
"xadc",
|
||||
"cpu_or_bridge",
|
||||
]
|
||||
csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
|
||||
|
||||
def __init__(self, platform, **kwargs):
|
||||
# clk_freq = int(100e6)
|
||||
self.integrated_main_ram_size = 8192
|
||||
self.add_memory()
|
||||
|
||||
def main():
|
||||
platform = Platform()
|
||||
soc = BaseSoC(platform)
|
||||
builder = Builder(soc, output_dir="build", csr_csv="test/csr.csv")
|
||||
vns = builder.build()
|
||||
soc.do_exit(vns)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
493
lxbuildenv.py
Normal file
493
lxbuildenv.py
Normal file
@ -0,0 +1,493 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script enables easy, cross-platform building without the need
|
||||
# to install third-party Python modules.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import argparse
|
||||
|
||||
|
||||
DEPS_DIR = "deps"
|
||||
|
||||
DEFAULT_DEPS = {
|
||||
'migen': 'https://github.com/m-labs/migen.git',
|
||||
'litex': 'https://github.com/enjoy-digital/litex.git',
|
||||
'litescope': 'https://github.com/enjoy-digital/litescope.git',
|
||||
'pyserial': 'https://github.com/pyserial/pyserial.git',
|
||||
'liteeth': 'https://github.com/enjoy-digital/liteeth.git',
|
||||
'liteusb': 'https://github.com/enjoy-digital/liteusb.git',
|
||||
'litedram': 'https://github.com/enjoy-digital/litedram.git',
|
||||
'litepcie': 'https://github.com/enjoy-digital/litepcie.git',
|
||||
'litesdcard': 'https://github.com/enjoy-digital/litesdcard.git',
|
||||
'liteiclink': 'https://github.com/enjoy-digital/liteiclink.git',
|
||||
'litevideo': 'https://github.com/enjoy-digital/litevideo.git',
|
||||
}
|
||||
|
||||
# Obtain the path to this script, plus a trailing separator. This will
|
||||
# be used later on to construct various environment variables for paths
|
||||
# to a variety of support directories.
|
||||
script_path = os.path.dirname(os.path.realpath(__file__)) + os.path.sep
|
||||
|
||||
# Look through the specified file for known variables to get the dependency list
|
||||
def get_required_dependencies(filename):
|
||||
import ast
|
||||
|
||||
# Always check the Python version
|
||||
dependencies = {
|
||||
'python': 1
|
||||
}
|
||||
main_src = ""
|
||||
|
||||
try:
|
||||
with open(sys.argv[0], 'r') as f:
|
||||
main_src = f.read()
|
||||
main_ast = ast.parse(main_src, filename=filename)
|
||||
except:
|
||||
return list(dependencies.keys())
|
||||
|
||||
# Iterate through the top-level nodes looking for variables named
|
||||
# LX_DEPENDENCIES or LX_DEPENDENCY and get the values that are
|
||||
# assigned to them.
|
||||
for node in ast.iter_child_nodes(main_ast):
|
||||
if isinstance(node, ast.Assign):
|
||||
value = node.value
|
||||
for target in node.targets:
|
||||
if isinstance(target, ast.Name):
|
||||
if target.id == "LX_DEPENDENCIES" or target.id == "LX_DEPENDENCY":
|
||||
if isinstance(value, (ast.List, ast.Tuple)):
|
||||
for elt in value.elts:
|
||||
if isinstance(elt, ast.Str):
|
||||
dependencies[elt.s] = 1
|
||||
elif isinstance(value, ast.Str):
|
||||
dependencies[value.s] = 1
|
||||
|
||||
# Set up sub-dependencies
|
||||
if 'riscv' in dependencies:
|
||||
dependencies['make'] = 1
|
||||
return list(dependencies.keys())
|
||||
|
||||
def get_python_path(script_path, args):
|
||||
# Python has no concept of a local dependency path, such as the C `-I``
|
||||
# switch, or the nodejs `node_modules` path, or the rust cargo registry.
|
||||
# Instead, it relies on an environment variable to append to the search
|
||||
# path.
|
||||
# Construct this variable by adding each subdirectory under the `deps/`
|
||||
# directory to the PYTHONPATH environment variable.
|
||||
python_path = []
|
||||
if os.path.isdir(script_path + DEPS_DIR):
|
||||
for dep in os.listdir(script_path + DEPS_DIR):
|
||||
dep = script_path + DEPS_DIR + os.path.sep + dep
|
||||
if os.path.isdir(dep):
|
||||
python_path.append(dep)
|
||||
return python_path
|
||||
|
||||
def fixup_env(script_path, args):
|
||||
os.environ["PYTHONPATH"] = os.pathsep.join(get_python_path(script_path, 0))
|
||||
|
||||
# Set the "LXBUILDENV_REEXEC" variable to prevent the script from continuously
|
||||
# reinvoking itself.
|
||||
os.environ["LXBUILDENV_REEXEC"] = "1"
|
||||
|
||||
# Python randomizes the order in which it traverses hashes, and Migen uses
|
||||
# hashes an awful lot when bringing together modules. As such, the order
|
||||
# in which Migen generates its output Verilog will change with every run,
|
||||
# and the addresses for various modules will change.
|
||||
# Make builds deterministic so that the generated Verilog code won't change
|
||||
# across runs.
|
||||
os.environ["PYTHONHASHSEED"] = "1"
|
||||
|
||||
# Some Makefiles are invoked as part of the build process, and those Makefiles
|
||||
# occasionally have calls to Python. Ensure those Makefiles use the same
|
||||
# interpreter that this script is using.
|
||||
os.environ["PYTHON"] = sys.executable
|
||||
|
||||
# Set the environment variable "V" to 1. This causes Makefiles to print
|
||||
# the commands they run, which makes them easier to debug.
|
||||
if "lx_verbose" in args and args.lx_verbose:
|
||||
os.environ["V"] = "1"
|
||||
|
||||
# If the user just wanted to print the environment variables, do that and quit.
|
||||
if args.lx_print_env:
|
||||
print("PYTHONPATH={}".format(os.environ["PYTHONPATH"]))
|
||||
print("PYTHONHASHSEED={}".format(os.environ["PYTHONHASHSEED"]))
|
||||
print("PYTHON={}".format(sys.executable))
|
||||
print("LXBUILDENV_REEXEC={}".format(os.environ["LXBUILDENV_REEXEC"]))
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# Equivalent to the powershell Get-Command, and kinda like `which`
|
||||
def get_command(cmd):
|
||||
if os.name == 'nt':
|
||||
path_ext = os.environ["PATHEXT"].split(os.pathsep)
|
||||
else:
|
||||
path_ext = [""]
|
||||
for ext in path_ext:
|
||||
for path in os.environ["PATH"].split(os.pathsep):
|
||||
|
||||
if os.path.exists(path + os.path.sep + cmd + ext):
|
||||
return path + os.path.sep + cmd + ext
|
||||
return None
|
||||
|
||||
def check_python_version(args):
|
||||
import platform
|
||||
# Litex / Migen require Python 3.5 or newer. Ensure we're running
|
||||
# under a compatible version of Python.
|
||||
if sys.version_info[:3] < (3, 5):
|
||||
return (False,
|
||||
"python: You need Python 3.5+ (version {} found)".format(sys.version_info[:3]))
|
||||
return (True, "python 3.5+: ok (Python {} found)".format(platform.python_version()))
|
||||
|
||||
def check_vivado(args):
|
||||
vivado_path = get_command("vivado")
|
||||
if vivado_path == None:
|
||||
# Look for the default Vivado install directory
|
||||
if os.name == 'nt':
|
||||
base_dir = r"C:\Xilinx\Vivado"
|
||||
else:
|
||||
base_dir = "/opt/Xilinx/Vivado"
|
||||
if os.path.exists(base_dir):
|
||||
for file in os.listdir(base_dir):
|
||||
bin_dir = base_dir + os.path.sep + file + os.path.sep + "bin"
|
||||
if os.path.exists(bin_dir + os.path.sep + "vivado"):
|
||||
os.environ["PATH"] += os.pathsep + bin_dir
|
||||
vivado_path = bin_dir
|
||||
break
|
||||
if vivado_path == None:
|
||||
return (False, "toolchain not found in your PATH", "download it from https://www.xilinx.com/support/download.html")
|
||||
return (True, "found at {}".format(vivado_path))
|
||||
|
||||
def check_cmd(args, cmd, name=None, fix=None):
|
||||
if name is None:
|
||||
name = cmd
|
||||
path = get_command(cmd)
|
||||
if path == None:
|
||||
return (False, name + " not found in your PATH", fix)
|
||||
return (True, "found at {}".format(path))
|
||||
|
||||
def check_make(args):
|
||||
return check_cmd(args, "make", "GNU Make")
|
||||
|
||||
def check_riscv(args):
|
||||
return check_cmd(args, "riscv64-unknown-elf-gcc", "riscv toolchain", "download it from https://www.sifive.com/products/tools/")
|
||||
|
||||
def check_yosys(args):
|
||||
return check_cmd(args, "yosys")
|
||||
|
||||
def check_arachne(args):
|
||||
return check_cmd(args, "arachne-pnr")
|
||||
|
||||
dependency_checkers = {
|
||||
'python': check_python_version,
|
||||
'vivado': check_vivado,
|
||||
'make': check_make,
|
||||
'riscv': check_riscv,
|
||||
'yosys': check_yosys,
|
||||
'arachne-pnr': check_arachne,
|
||||
}
|
||||
|
||||
# Validate that the required dependencies (Vivado, compilers, etc.)
|
||||
# have been installed.
|
||||
def check_dependencies(args, dependency_list):
|
||||
|
||||
dependency_errors = 0
|
||||
for dependency_name in dependency_list:
|
||||
if not dependency_name in dependency_checkers:
|
||||
print('WARNING: Unrecognized dependency "{}"'.format(dependency_name))
|
||||
continue
|
||||
result = dependency_checkers[dependency_name](args)
|
||||
if result[0] == False:
|
||||
if len(result) > 2:
|
||||
print('{}: {} -- {}'.format(dependency_name, result[1], result[2]))
|
||||
else:
|
||||
print('{}: {}'.format(dependency_name, result[1]))
|
||||
dependency_errors = dependency_errors + 1
|
||||
|
||||
elif args.lx_check_deps or args.lx_verbose:
|
||||
print('dependency: {}: {}'.format(dependency_name, result[1]))
|
||||
if dependency_errors > 0:
|
||||
if args.lx_ignore_deps:
|
||||
print('{} missing dependencies were found but continuing anyway'.format(dependency_errors))
|
||||
else:
|
||||
raise SystemExit(str(dependency_errors) +
|
||||
" missing dependencies were found")
|
||||
|
||||
if args.lx_check_deps:
|
||||
sys.exit(0)
|
||||
|
||||
# Return True if the given tree needs to be initialized
|
||||
def check_module_recursive(root_path, depth, verbose=False):
|
||||
if verbose:
|
||||
print('git-dep: checking if "{}" requires updating...'.format(root_path))
|
||||
# If the directory isn't a valid git repo, initialization is required
|
||||
if not os.path.exists(root_path + os.path.sep + '.git'):
|
||||
return True
|
||||
|
||||
# If there are no submodules, no initialization needs to be done
|
||||
if not os.path.isfile(root_path + os.path.sep + '.gitmodules'):
|
||||
return False
|
||||
|
||||
# Loop through the gitmodules to check all submodules
|
||||
gitmodules = open(root_path + os.path.sep + '.gitmodules', 'r')
|
||||
for line in gitmodules:
|
||||
parts = line.split("=", 2)
|
||||
if parts[0].strip() == "path":
|
||||
path = parts[1].strip()
|
||||
if check_module_recursive(root_path + os.path.sep + path, depth + 1, verbose=verbose):
|
||||
return True
|
||||
return False
|
||||
|
||||
# Determine whether we need to invoke "git submodules init --recurse"
|
||||
def check_submodules(script_path, args):
|
||||
if check_module_recursive(script_path, 0, verbose=args.lx_verbose):
|
||||
print("Missing submodules -- updating")
|
||||
subprocess.Popen(["git", "submodule", "update",
|
||||
"--init", "--recursive"], cwd=script_path).wait()
|
||||
elif args.lx_verbose:
|
||||
print("Submodule check: Submodules found")
|
||||
|
||||
|
||||
def lx_git(cmd, *args):
|
||||
import subprocess
|
||||
git_cmd = ["git", cmd]
|
||||
if args is not None:
|
||||
for arg in args:
|
||||
git_cmd = git_cmd + [arg]
|
||||
subprocess.call(git_cmd)
|
||||
|
||||
def lx_print_deps():
|
||||
print('Known dependencies:')
|
||||
for dep in dependency_checkers.keys():
|
||||
print(' {}'.format(dep))
|
||||
print('To define a dependency, add a variable inside {} at the top level called LX_DEPENDENCIES and assign it a list or tuple.'.format(sys.argv[0]))
|
||||
print('For example:')
|
||||
print('LX_DEPENDENCIES = ("riscv", "vivado")')
|
||||
|
||||
|
||||
def lx_main(args):
|
||||
if args.lx_print_env:
|
||||
fixup_env(script_path, args)
|
||||
|
||||
elif args.lx_print_deps:
|
||||
lx_print_deps()
|
||||
|
||||
elif args.init:
|
||||
if args.main is None:
|
||||
main_name = os.getcwd().split(os.path.sep)[-1] + '.py'
|
||||
new_main_name = input('What would you like your main program to be called? [' + main_name + '] ')
|
||||
if new_main_name is not None and new_main_name != "":
|
||||
main_name = new_main_name
|
||||
else:
|
||||
main_name = args.main
|
||||
if not main_name.endswith('.py'):
|
||||
main_name = main_name + '.py'
|
||||
|
||||
if args.no_git:
|
||||
print("skipping git initialization")
|
||||
else:
|
||||
if not os.path.exists(DEPS_DIR):
|
||||
os.mkdir(DEPS_DIR)
|
||||
|
||||
if not os.path.exists(".git"):
|
||||
print("initializing git repository")
|
||||
lx_git('init')
|
||||
else:
|
||||
print("using existing git repository")
|
||||
lx_git('add', str(__file__))
|
||||
|
||||
for dep_name, dep_url in DEFAULT_DEPS.items():
|
||||
dest_path = '{}{}{}'.format(DEPS_DIR, '/', dep_name)
|
||||
if not os.path.exists(dest_path):
|
||||
lx_git('submodule', 'add', dep_url, dest_path)
|
||||
lx_git('add', dest_path)
|
||||
|
||||
lx_git('submodule', 'update', '--init', '--recursive')
|
||||
|
||||
if args.no_bin:
|
||||
print("skipping bin/ initialization")
|
||||
elif os.path.exists("bin"):
|
||||
print("bin/ directory exists -- remove bin/ directory to re-initialize")
|
||||
else:
|
||||
bin_tools = {
|
||||
'mkmscimg': 'litex.soc.tools.mkmscimg',
|
||||
'litex_term': 'litex.utils.litex_term',
|
||||
'litex_server': 'litex.utils.litex_server',
|
||||
'litex_sim': 'litex.utils.litex_sim',
|
||||
'litex_read_verilog': 'litex.utils.litex_read_verilog',
|
||||
'litex_simple': 'litex.boards.targets.simple',
|
||||
}
|
||||
bin_template = """#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# This script lives in the "bin" directory, but uses a helper script in the parent
|
||||
# directory. Obtain the current path so we can get the absolute parent path.
|
||||
script_path = os.path.dirname(os.path.realpath(
|
||||
__file__)) + os.path.sep + os.path.pardir + os.path.sep
|
||||
sys.path.insert(0, script_path)
|
||||
import lxbuildenv
|
||||
|
||||
"""
|
||||
print("Creating binaries")
|
||||
os.mkdir("bin")
|
||||
for bin_name, python_module in bin_tools.items():
|
||||
with open('bin' + os.path.sep + bin_name, 'w') as new_bin:
|
||||
new_bin.write(bin_template)
|
||||
new_bin.write('from ' + python_module + ' import main\n')
|
||||
new_bin.write('main()\n')
|
||||
import stat
|
||||
os.chmod('bin' + os.path.sep + bin_name, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||
if not args.no_git:
|
||||
lx_git('add', '--chmod=+x', 'bin' + os.path.sep + bin_name)
|
||||
|
||||
if os.path.exists(main_name):
|
||||
print("skipping creation of {}: file exists".format(main_name))
|
||||
else:
|
||||
print("creating main program {}".format(main_name))
|
||||
with open(main_name, 'w') as m:
|
||||
program_template = """#!/usr/bin/env python3
|
||||
# This variable defines all the external programs that this module
|
||||
# relies on. lxbuildenv reads this variable in order to ensure
|
||||
# the build will finish without exiting due to missing third-party
|
||||
# programs.
|
||||
LX_DEPENDENCIES = ["riscv", "vivado"]
|
||||
|
||||
# Import lxbuildenv to integrate the deps/ directory
|
||||
import lxbuildenv
|
||||
|
||||
# Disable pylint's E1101, which breaks completely on migen
|
||||
#pylint:disable=E1101
|
||||
|
||||
from migen import *
|
||||
from litex.build.generic_platform import *
|
||||
|
||||
_io = [
|
||||
("clk50", 0, Pins("J19"), IOStandard("LVCMOS33")),
|
||||
]
|
||||
|
||||
class Platform(XilinxPlatform):
|
||||
def __init__(self, toolchain="vivado", programmer="vivado", part="35"):
|
||||
part = "xc7a" + part + "t-fgg484-2"
|
||||
def create_programmer(self):
|
||||
if self.programmer == "vivado":
|
||||
return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4")
|
||||
else:
|
||||
raise ValueError("{} programmer is not supported"
|
||||
.format(self.programmer))
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
|
||||
class BaseSoC(SoCSDRAM):
|
||||
csr_peripherals = [
|
||||
"ddrphy",
|
||||
# "dna",
|
||||
"xadc",
|
||||
"cpu_or_bridge",
|
||||
]
|
||||
csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
|
||||
|
||||
def __init__(self, platform, **kwargs):
|
||||
clk_freq = int(100e6)
|
||||
|
||||
def main():
|
||||
platform = Platform()
|
||||
soc = BaseSoC(platform)
|
||||
builder = Builder(soc, output_dir="build", csr_csv="test/csr.csv")
|
||||
vns = builder.build()
|
||||
soc.do_exit(vns)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
"""
|
||||
m.write(program_template)
|
||||
if not args.no_git:
|
||||
lx_git("add", main_name)
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
# For the main command, parse args and hand it off to main()
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Wrap Python code to enable quickstart",
|
||||
add_help=False)
|
||||
parser.add_argument(
|
||||
"-h", "--help", '--lx-help', help="show this help message and exit", action="help"
|
||||
)
|
||||
parser.add_argument(
|
||||
'-i', '--init', '--lx-init', help='initialize a new project', action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
'-m', '--main', '--lx-main', help='name of main project'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-bin', '--lx-no-bin', help="don't create a bin/ directory"
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-git', '--lx-no-git', help="Don't create a git repository"
|
||||
)
|
||||
parser.add_argument(
|
||||
'-e', '--print-env', '--lx-print-env', dest="lx_print_env", help="print environment variable listing for pycharm, vscode, or bash", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
'-d', '--print-deps', '--lx-print-deps', dest="lx_print_deps", help="print all possible dependencies and then exit", action="store_true"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not lx_main(args):
|
||||
parser.print_help()
|
||||
|
||||
elif not os.path.isfile(sys.argv[0]):
|
||||
print("lxbuildenv doesn't operate while in interactive mode")
|
||||
|
||||
elif "LXBUILDENV_REEXEC" not in os.environ:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Wrap Python code to enable quickstart",
|
||||
add_help=False)
|
||||
parser.add_argument(
|
||||
"--lx-verbose", help="increase verboseness of some processes", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lx-print-env", help="print environment variable listing for pycharm, vscode, or bash", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lx-check-deps", help="check build environment for dependencies such as compiler and fpga tools and then exit", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lx-print-deps", help="print all possible dependencies and then exit", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lx-help", action="help"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lx-ignore-deps", help="try building even if dependencies are missing", action="store_true"
|
||||
)
|
||||
(args, rest) = parser.parse_known_args()
|
||||
|
||||
if args.lx_print_deps:
|
||||
lx_print_deps()
|
||||
sys.exit(0)
|
||||
|
||||
deps = get_required_dependencies(sys.argv[0])
|
||||
|
||||
fixup_env(script_path, args)
|
||||
check_dependencies(args, deps)
|
||||
check_submodules(script_path, args)
|
||||
|
||||
try:
|
||||
sys.exit(subprocess.Popen(
|
||||
[sys.executable] + [sys.argv[0]] + rest).wait())
|
||||
except:
|
||||
sys.exit(1)
|
||||
else:
|
||||
# Overwrite the deps directory.
|
||||
# Because we're running with a predefined PYTHONPATH, you'd think that
|
||||
# the DEPS_DIR would be first.
|
||||
# Unfortunately, setuptools causes the sitewide packages to take precedence
|
||||
# over the PYTHONPATH variable.
|
||||
# Work around this bug by inserting paths into the first index.
|
||||
for path in get_python_path(script_path, None):
|
||||
sys.path.insert(0, path)
|
Loading…
Reference in New Issue
Block a user