build/microsemi/libero_soc: add timing constraints support
This commit is contained in:
parent
60faae490a
commit
4c966114f8
|
@ -87,7 +87,7 @@ def _build_tcl(platform, sources, build_dir, build_name):
|
|||
"-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:
|
||||
|
@ -102,7 +102,7 @@ def _build_tcl(platform, sources, build_dir, build_name):
|
|||
if file.endswith(".init"):
|
||||
tcl.append("file copy -- {} impl/synthesis".format(file))
|
||||
|
||||
# import constraints
|
||||
# import io constraints
|
||||
tcl.append("import_files -io_pdc {{{}}}".format(build_name + ".pdc"))
|
||||
tcl.append(" ".join(["organize_tool_files",
|
||||
"-tool {PLACEROUTE}",
|
||||
|
@ -111,6 +111,15 @@ def _build_tcl(platform, sources, build_dir, build_name):
|
|||
"-input_type {constraint}"
|
||||
]))
|
||||
|
||||
# import timing constraints
|
||||
tcl.append("import_files -convert_EDN_to_HDL 0 -sdc {{{}}}".format(build_name + ".sdc"))
|
||||
tcl.append(" ".join(["organize_tool_files",
|
||||
"-tool {VERIFYTIMING}",
|
||||
"-file impl/constraint/{}.sdc".format(build_name),
|
||||
"-module {}".format(build_name),
|
||||
"-input_type {constraint}"
|
||||
]))
|
||||
|
||||
# build flow
|
||||
tcl.append("run_tool -name {CONSTRAINT_MANAGEMENT}")
|
||||
tcl.append("run_tool -name {SYNTHESIZE}")
|
||||
|
@ -129,6 +138,24 @@ def _build_tcl(platform, sources, build_dir, build_name):
|
|||
tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
|
||||
|
||||
|
||||
def _build_sdc(vns, clocks, false_paths, build_name):
|
||||
sdc = []
|
||||
|
||||
for clk, period in sorted(clocks.items(), key=lambda x: x[0].duid):
|
||||
sdc.append(
|
||||
"create_clock -name {clk} -period " + str(period) +
|
||||
" [get_nets {clk}]".format(clk=vns.get_name(clk)))
|
||||
for from_, to in sorted(false_paths,
|
||||
key=lambda x: (x[0].duid, x[1].duid)):
|
||||
sdc.append(
|
||||
"set_clock_groups "
|
||||
"-group [get_clocks -include_generated_clocks -of [get_nets {from_}]] "
|
||||
"-group [get_clocks -include_generated_clocks -of [get_nets {to}]] "
|
||||
"-asynchronous".format(from_=from_, to=to))
|
||||
|
||||
# generate sdc
|
||||
tools.write_to_file(build_name + ".sdc", "\n".join(sdc))
|
||||
|
||||
def _build_script(build_name, device, toolchain_path, ver=None):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
script_ext = ".bat"
|
||||
|
@ -170,6 +197,10 @@ class MicrosemiLiberoSoCPolarfireToolchain:
|
|||
|
||||
special_overrides = common.microsemi_polarfire_special_overrides
|
||||
|
||||
def __init__(self):
|
||||
self.clocks = dict()
|
||||
self.false_paths = set()
|
||||
|
||||
def build(self, platform, fragment, build_dir="build", build_name="top",
|
||||
toolchain_path=None, run=False, **kwargs):
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
|
@ -190,9 +221,12 @@ class MicrosemiLiberoSoCPolarfireToolchain:
|
|||
# generate design script (tcl)
|
||||
_build_tcl(platform, platform.sources, build_dir, build_name)
|
||||
|
||||
# generate design constraints (pdc)
|
||||
# generate design io constraints (pdc)
|
||||
_build_pdc(named_sc, named_pc, build_name)
|
||||
|
||||
# generate design timing constraints (sdc)
|
||||
_build_sdc(top_output.ns, self.clocks, self.false_paths, build_name)
|
||||
|
||||
# generate build script
|
||||
script = _build_script(build_name, platform.device, toolchain_path)
|
||||
|
||||
|
@ -205,4 +239,10 @@ class MicrosemiLiberoSoCPolarfireToolchain:
|
|||
return top_output.ns
|
||||
|
||||
def add_period_constraint(self, platform, clk, period):
|
||||
print("TODO: add_period_constraint")
|
||||
if clk in self.clocks:
|
||||
raise ValueError("A period constraint already exists")
|
||||
self.clocks[clk] = period
|
||||
|
||||
def add_false_path_constraint(self, platform, from_, to):
|
||||
if (to, from_) not in self.false_paths:
|
||||
self.false_paths.add((from_, to))
|
||||
|
|
|
@ -13,7 +13,7 @@ class MicrosemiPlatform(GenericPlatform):
|
|||
raise ValueError("Unknown toolchain")
|
||||
|
||||
def get_verilog(self, *args, special_overrides=dict(), **kwargs):
|
||||
so = dict() # No common overrides between ECP and ice40.
|
||||
so = dict()
|
||||
so.update(self.toolchain.special_overrides)
|
||||
so.update(special_overrides)
|
||||
return GenericPlatform.get_verilog(self, *args, special_overrides=so,
|
||||
|
@ -27,3 +27,10 @@ class MicrosemiPlatform(GenericPlatform):
|
|||
if hasattr(clk, "p"):
|
||||
clk = clk.p
|
||||
self.toolchain.add_period_constraint(self, clk, period)
|
||||
|
||||
def add_false_path_constraint(self, from_, to):
|
||||
if hasattr(from_, "p"):
|
||||
from_ = from_.p
|
||||
if hasattr(to, "p"):
|
||||
to = to.p
|
||||
self.toolchain.add_false_path_constraint(self, from_, to)
|
||||
|
|
Loading…
Reference in New Issue