mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
build/microsemi/libero_soc: able to generate design script (tcl) and design constraint (pdc) for libero soc / avalanche board.
This commit is contained in:
parent
4cb6583b4e
commit
45ec78e93a
1 changed files with 128 additions and 10 deletions
|
@ -12,8 +12,116 @@ from litex.build.generic_platform import *
|
||||||
from litex.build import tools
|
from litex.build import tools
|
||||||
from litex.build.microsemi import common
|
from litex.build.microsemi import common
|
||||||
|
|
||||||
def _build_files(device, sources, vincpaths, build_name):
|
def _format_constraint(c):
|
||||||
print("TODO: _build_files")
|
if isinstance(c, Pins):
|
||||||
|
return "-pin_name {} ".format(c.identifiers[0])
|
||||||
|
elif isinstance(c, IOStandard):
|
||||||
|
return "-io_std {} ".format(c.name)
|
||||||
|
elif isinstance(c, Misc):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def _format_pdc(signame, pin, others):
|
||||||
|
fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)]
|
||||||
|
r = "set_io "
|
||||||
|
r += "-port_name {} ".format(signame)
|
||||||
|
for c in ([Pins(pin)] + others):
|
||||||
|
r += _format_constraint(c)
|
||||||
|
r += "-fixed true "
|
||||||
|
r += "\n"
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def _build_pdc(named_sc, named_pc, build_name):
|
||||||
|
pdc = ""
|
||||||
|
for sig, pins, others, resname in named_sc:
|
||||||
|
if len(pins) > 1:
|
||||||
|
for i, p in enumerate(pins):
|
||||||
|
pdc += _format_pdc(sig + "[" + str(i) + "]", p, others)
|
||||||
|
else:
|
||||||
|
pdc += _format_pdc(sig, pins[0], others)
|
||||||
|
tools.write_to_file(build_name + ".pdc", pdc)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_tcl(platform, sources, build_dir, build_name):
|
||||||
|
tcl = []
|
||||||
|
|
||||||
|
# create project
|
||||||
|
tcl.append(" ".join([
|
||||||
|
"new_project",
|
||||||
|
"-location {./impl}",
|
||||||
|
"-name {{{}}}".format(build_name),
|
||||||
|
"-project_description {}",
|
||||||
|
"-block_mode 0",
|
||||||
|
"-standalone_peripheral_initialization 0",
|
||||||
|
"-instantiate_in_smartdesign 1",
|
||||||
|
"-ondemand_build_dh 0",
|
||||||
|
"-use_enhanced_constraint_flow 0",
|
||||||
|
"-hdl {VERILOG}",
|
||||||
|
"-family {PolarFire}",
|
||||||
|
"-die {}",
|
||||||
|
"-package {}",
|
||||||
|
"-speed {}",
|
||||||
|
"-die_voltage {}",
|
||||||
|
"-part_range {}",
|
||||||
|
"-adv_options {}"
|
||||||
|
]))
|
||||||
|
|
||||||
|
# set device FIXME: use platform device
|
||||||
|
tcl.append(" ".join([
|
||||||
|
"set_device",
|
||||||
|
"-family {PolarFire}",
|
||||||
|
"-die {MPF300TS_ES}",
|
||||||
|
"-package {FCG484}",
|
||||||
|
"-speed {-1}",
|
||||||
|
"-die_voltage {1.0}",
|
||||||
|
"-part_range {EXT}",
|
||||||
|
"-adv_options {IO_DEFT_STD:LVCMOS 1.8V}",
|
||||||
|
"-adv_options {RESTRICTPROBEPINS:1}",
|
||||||
|
"-adv_options {RESTRICTSPIPINS:0}",
|
||||||
|
"-adv_options {TEMPR:EXT}",
|
||||||
|
"-adv_options {UNUSED_MSS_IO_RESISTOR_PULL:None}",
|
||||||
|
"-adv_options {VCCI_1.2_VOLTR:EXT}",
|
||||||
|
"-adv_options {VCCI_1.5_VOLTR:EXT}",
|
||||||
|
"-adv_options {VCCI_1.8_VOLTR:EXT}",
|
||||||
|
"-adv_options {VCCI_2.5_VOLTR:EXT}",
|
||||||
|
"-adv_options {VCCI_3.3_VOLTR:EXT}",
|
||||||
|
"-adv_options {VOLTR:EXT} "
|
||||||
|
]))
|
||||||
|
|
||||||
|
# add files
|
||||||
|
for filename, language, library in sources:
|
||||||
|
filename_tcl = "{" + filename + "}"
|
||||||
|
tcl.append("import_files -hdl_source " + filename_tcl)
|
||||||
|
|
||||||
|
# set top
|
||||||
|
tcl.append("set_root -module {{{}}}".format(build_name))
|
||||||
|
|
||||||
|
# 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 constraints
|
||||||
|
tcl.append("import_files -io_pdc {{{}}}".format(build_name + ".pdc"))
|
||||||
|
|
||||||
|
# build flow
|
||||||
|
tcl.append("run_tool -name {CONSTRAINT_MANAGEMENT}")
|
||||||
|
tcl.append("run_tool -name {SYNTHESIZE}")
|
||||||
|
tcl.append(" ".join([
|
||||||
|
"configure_tool",
|
||||||
|
"-name {PLACEROUTE}",
|
||||||
|
"-params {EFFORT_LEVEL:true}",
|
||||||
|
"-params {REPAIR_MIN_DELAY:true}",
|
||||||
|
"-params {TDPR:true}"
|
||||||
|
]))
|
||||||
|
tcl.append("run_tool -name {PLACEROUTE}")
|
||||||
|
tcl.append("run_tool -name {GENERATEPROGRAMMINGDATA}")
|
||||||
|
tcl.append("run_tool -name {GENERATEPROGRAMMINGFILE}")
|
||||||
|
|
||||||
|
# generate tcl
|
||||||
|
tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
|
||||||
|
|
||||||
|
|
||||||
def _build_script(build_name, device, toolchain_path, ver=None):
|
def _build_script(build_name, device, toolchain_path, ver=None):
|
||||||
if sys.platform in ("win32", "cygwin"):
|
if sys.platform in ("win32", "cygwin"):
|
||||||
|
@ -29,6 +137,7 @@ def _build_script(build_name, device, toolchain_path, ver=None):
|
||||||
force_unix=False)
|
force_unix=False)
|
||||||
return build_script_file
|
return build_script_file
|
||||||
|
|
||||||
|
|
||||||
def _run_script(script):
|
def _run_script(script):
|
||||||
if sys.platform in ("win32", "cygwin"):
|
if sys.platform in ("win32", "cygwin"):
|
||||||
shell = ["cmd", "/c"]
|
shell = ["cmd", "/c"]
|
||||||
|
@ -56,7 +165,7 @@ class MicrosemiLiberoSoCPolarfireToolchain:
|
||||||
special_overrides = common.microsemi_polarfire_special_overrides
|
special_overrides = common.microsemi_polarfire_special_overrides
|
||||||
|
|
||||||
def build(self, platform, fragment, build_dir="build", build_name="top",
|
def build(self, platform, fragment, build_dir="build", build_name="top",
|
||||||
toolchain_path=None, run=True, **kwargs):
|
toolchain_path=None, run=False, **kwargs):
|
||||||
os.makedirs(build_dir, exist_ok=True)
|
os.makedirs(build_dir, exist_ok=True)
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
os.chdir(build_dir)
|
os.chdir(build_dir)
|
||||||
|
@ -65,20 +174,29 @@ class MicrosemiLiberoSoCPolarfireToolchain:
|
||||||
fragment = fragment.get_fragment()
|
fragment = fragment.get_fragment()
|
||||||
platform.finalize(fragment)
|
platform.finalize(fragment)
|
||||||
|
|
||||||
v_output = platform.get_verilog(fragment, name=build_name, **kwargs)
|
# generate verilog
|
||||||
named_sc, named_pc = platform.resolve_signals(v_output.ns)
|
top_output = platform.get_verilog(fragment, name=build_name, **kwargs)
|
||||||
v_file = build_name + ".v"
|
named_sc, named_pc = platform.resolve_signals(top_output.ns)
|
||||||
v_output.write(v_file)
|
top_file = build_name + ".v"
|
||||||
sources = platform.sources | {(v_file, "verilog", "work")}
|
top_output.write(top_file)
|
||||||
_build_files(platform.device, sources, platform.verilog_include_paths, build_name)
|
platform.add_source(top_file)
|
||||||
|
|
||||||
|
# generate design script (tcl)
|
||||||
|
_build_tcl(platform, platform.sources, build_dir, build_name)
|
||||||
|
|
||||||
|
# generate design constraints (pdc)
|
||||||
|
_build_pdc(named_sc, named_pc, build_name)
|
||||||
|
|
||||||
|
# generate build script
|
||||||
script = _build_script(build_name, platform.device, toolchain_path)
|
script = _build_script(build_name, platform.device, toolchain_path)
|
||||||
|
|
||||||
|
# run
|
||||||
if run:
|
if run:
|
||||||
_run_script(script)
|
_run_script(script)
|
||||||
|
|
||||||
os.chdir(cwd)
|
os.chdir(cwd)
|
||||||
|
|
||||||
return v_output.ns
|
return top_output.ns
|
||||||
|
|
||||||
def add_period_constraint(self, platform, clk, period):
|
def add_period_constraint(self, platform, clk, period):
|
||||||
print("TODO: add_period_constraint")
|
print("TODO: add_period_constraint")
|
Loading…
Reference in a new issue