Skip to content

Commit

Permalink
build/xx/toolchains: allows override clock naming
Browse files Browse the repository at this point in the history
  • Loading branch information
trabucayre committed Aug 31, 2023
1 parent 2a7caa2 commit c7f947a
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 38 deletions.
4 changes: 2 additions & 2 deletions litex/build/altera/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def get_verilog(self, *args, special_overrides=dict(), **kwargs):
def build(self, *args, **kwargs):
return self.toolchain.build(self, *args, **kwargs)

def add_period_constraint(self, clk, period, keep=False):
self.toolchain.add_period_constraint(self, clk, period, keep=False)
def add_period_constraint(self, clk, period, keep=False, name=None):
self.toolchain.add_period_constraint(self, clk, period, keep=keep, name=name)

def add_false_path_constraint(self, from_, to):
if hasattr(from_, "p"):
Expand Down
13 changes: 8 additions & 5 deletions litex/build/altera/quartus.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,20 @@ def build_timing_constraints(self, vns):
sdc = []

# Clock constraints
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
is_port = False
for sig, pins, others, resname in self.named_sc:
if sig == vns.get_name(clk):
is_port = True
clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig
if is_port:
tpl = "create_clock -name {clk} -period {period} [get_ports {{{clk}}}]"
sdc.append(tpl.format(clk=vns.get_name(clk), period=str(period)))
tpl = "create_clock -name {name} -period {period} [get_ports {{{clk}}}]"
sdc.append(tpl.format(name=name, clk=clk_sig), period=str(period)))
else:
tpl = "create_clock -name {clk} -period {period} [get_nets {{{clk}}}]"
sdc.append(tpl.format(clk=vns.get_name(clk), period=str(period)))
tpl = "create_clock -name {name} -period {period} [get_nets {{{clk}}}]"
sdc.append(tpl.format(name=name, clk=clk_sig), period=str(period)))

# Enable automatical constraint generation for PLLs
sdc.append("derive_pll_clocks -use_net_name")
Expand Down
7 changes: 5 additions & 2 deletions litex/build/anlogic/anlogic.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ def build_io_constraints(self):

def build_timing_constraints(self, vns):
sdc = []
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
sdc.append(f"create_clock -name {vns.get_name(clk)} -period {str(period)} [get_ports {{{vns.get_name(clk)}}}]")
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig
sdc.append(f"create_clock -name {name} -period {str(period)} [get_ports {{{clk_sig}}}]")
tools.write_to_file("top.sdc", "\n".join(sdc))
return ("top.sdc", "SDC")

Expand Down
15 changes: 10 additions & 5 deletions litex/build/efinix/efinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,22 @@ def build_timing_constraints(self, vns):
sdc = []

# Clock constraints
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
is_port = False
for sig, pins, others, resname in self.named_sc:
if sig == self._vns.get_name(clk):
is_port = True

clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig

if is_port:
tpl = "create_clock -name {clk} -period {period} [get_ports {{{clk}}}]"
sdc.append(tpl.format(clk=self._vns.get_name(clk), period=str(period)))
tpl = "create_clock -name {name} -period {period} [get_ports {{{clk}}}]"
sdc.append(tpl.format(name=name, clk=clk_sig, period=str(period)))
else:
tpl = "create_clock -name {clk} -period {period} [get_nets {{{clk}}}]"
sdc.append(tpl.format(clk=self._vns.get_name(clk), period=str(period)))
tpl = "create_clock -name {name} -period {period} [get_nets {{{clk}}}]"
sdc.append(tpl.format(name=name, clk=clk_sig, period=str(period)))

# False path constraints
for from_, to in sorted(self.false_paths, key=lambda x: (x[0].duid, x[1].duid)):
Expand Down
4 changes: 2 additions & 2 deletions litex/build/generic_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,8 @@ def request_remaining(self, *args, **kwargs):
def lookup_request(self, *args, **kwargs):
return self.constraint_manager.lookup_request(*args, **kwargs)

def add_period_constraint(self, clk, period, keep=True):
self.toolchain.add_period_constraint(self, clk, period, keep=keep)
def add_period_constraint(self, clk, period, keep=True, name=None):
self.toolchain.add_period_constraint(self, clk, period, keep=keep, name=name)

def add_false_path_constraint(self, from_, to):
raise NotImplementedError
Expand Down
6 changes: 3 additions & 3 deletions litex/build/generic_toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def build(self, platform, fragment,

return v_output.ns

def add_period_constraint(self, platform, clk, period, keep=True):
def add_period_constraint(self, platform, clk, period, keep=True, name=None):
if clk is None:
return
if hasattr(clk, "p"):
Expand All @@ -171,10 +171,10 @@ def add_period_constraint(self, platform, clk, period, keep=True):
clk.attr.add("keep")
period = math.floor(period*1e3)/1e3 # Round to lowest picosecond.
if clk in self.clocks:
if period != self.clocks[clk]:
if period != self.clocks[clk][0]:
raise ValueError("Clock already constrained to {:.2f}ns, new constraint to {:.2f}ns"
.format(self.clocks[clk], period))
self.clocks[clk] = period
self.clocks[clk] = [period, name]

def add_false_path_constraint(self, platform, from_, to, keep=True):
if keep:
Expand Down
7 changes: 5 additions & 2 deletions litex/build/gowin/gowin.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ def build_io_constraints(self):

def build_timing_constraints(self, vns):
sdc = []
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
sdc.append(f"create_clock -name {vns.get_name(clk)} -period {str(period)} [get_ports {{{vns.get_name(clk)}}}]")
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig
sdc.append(f"create_clock -name {name} -period {str(period)} [get_ports {{{clk_sig}}}]")
tools.write_to_file(f"{self._build_name}.sdc", "\n".join(sdc))
return (f"{self._build_name}.sdc", "SDC")

Expand Down
2 changes: 1 addition & 1 deletion litex/build/lattice/diamond.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def build_io_constraints(self):
lpf.append("\n".join(self.named_pc))

# Note: .lpf is only used post-synthesis, Synplify constraints clocks by default to 200MHz.
for clk, period in self.clocks.items():
for clk, [period, _] in self.clocks.items():
clk_name = self._vns.get_name(clk)
lpf.append("FREQUENCY {} \"{}\" {} MHz;".format(
"PORT" if clk_name in [name for name, _, _, _ in self.named_sc] else "NET",
Expand Down
2 changes: 1 addition & 1 deletion litex/build/lattice/icestorm.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def build_io_constraints(self):

def build_timing_constraints(self, vns):
r = ""
for clk, period in self.clocks.items():
for clk, [period, _] in self.clocks.items():
r += """ctx.addClock("{}", {})\n""".format(vns.get_name(clk), 1e3/period)
tools.write_to_file(self._build_name + "_pre_pack.py", r)
return (self._build_name + "_pre_pack.py", "PY")
Expand Down
10 changes: 6 additions & 4 deletions litex/build/lattice/radiant.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ def _build_pdc(named_sc, named_pc, clocks, vns, build_name):
pdc.append("\n".join(named_pc))

# Note: .pdc is only used post-synthesis, Synplify constraints clocks by default to 200MHz.
for clk, period in clocks.items():
clk_name = vns.get_name(clk)
for clk, [period, clk_name] in clocks.items():
clk_sig = vns.get_name(clk)
if clk_name is None:
clk_name = clk_sig
pdc.append("create_clock -period {} -name {} [{} {}];".format(
str(period),
clk_name,
"get_ports" if clk_name in [name for name, _, _, _ in named_sc] else "get_nets",
clk_name
"get_ports" if clk_sig in [name for name, _, _, _ in named_sc] else "get_nets",
clk_sig
))

tools.write_to_file(build_name + ".pdc", "\n".join(pdc))
Expand Down
2 changes: 1 addition & 1 deletion litex/build/lattice/trellis.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def nextpnr_ecp5_parse_device(self, device):
"lfe5um5g-85f": "um5g-85k",
}

def add_period_constraint(self, platform, clk, period):
def add_period_constraint(self, platform, clk, period, name=None):
if clk is None:
return
if hasattr(clk, "p"):
Expand Down
9 changes: 6 additions & 3 deletions litex/build/microsemi/libero_soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,13 @@ def build_project(self):
def build_timing_constraints(self, vns):
sdc = []

for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig
sdc.append(
"create_clock -name {clk} -period " + str(period) +
" [get_nets {clk}]".format(clk=vns.get_name(clk)))
"create_clock -name {name} -period " + str(period) +
" [get_nets {clk}]".format(name=name, clk=clk_sig))
for from_, to in sorted(self.false_paths,
key=lambda x: (x[0].duid, x[1].duid)):
sdc.append(
Expand Down
7 changes: 5 additions & 2 deletions litex/build/osfpga/osfpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ def build_io_constraints(self):

def build_timing_constraints(self, vns):
sdc = []
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
sdc.append(f"create_clock -name {vns.get_name(clk)} -period {str(period)} [get_ports {{{vns.get_name(clk)}}}]")
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig
sdc.append(f"create_clock -name {name} -period {str(period)} [get_ports {{{clk_sig}}}]")
with open(f"{self._build_name}.sdc", "w") as f:
f.write("\n".join(sdc))
return (self._build_name + ".sdc", "SDC")
Expand Down
2 changes: 1 addition & 1 deletion litex/build/xilinx/f4pga.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def build_io_constraints(self):

def build_timing_constraints(self, vns):
self.platform.add_platform_command(_xdc_separator("Clock constraints"))
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
self.platform.add_platform_command(
"create_clock -period " + str(period) +
" {clk}", clk=clk)
Expand Down
2 changes: 1 addition & 1 deletion litex/build/xilinx/ise.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def run_script(self, script):
# constraints and other constraints otherwise it will be unable to trace
# them through clock objects like DCM and PLL objects.

def add_period_constraint(self, platform, clk, period, keep=True):
def add_period_constraint(self, platform, clk, period, keep=True, name=None):
if clk is None:
return
if hasattr(clk, "p"):
Expand Down
9 changes: 6 additions & 3 deletions litex/build/xilinx/vivado.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,13 @@ def get_clk_type(clk):
False : "nets",
True : "ports",
}[hasattr(clk, "port")]
for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
clk_sig = self._vns.get_name(clk)
if name is None:
name = clk_sig
self.platform.add_platform_command(
"create_clock -name {clk} -period " + str(period) +
" [get_" + get_clk_type(clk) + " {clk}]", clk=clk)
"create_clock -name {name} -period " + str(period) +
" [get_" + get_clk_type(clk) + " {clk}]", name=name, clk=clk)
for _from, _to in sorted(self.false_paths, key=lambda x: (x[0].duid, x[1].duid)):
self.platform.add_platform_command(
"set_clock_groups "
Expand Down

0 comments on commit c7f947a

Please sign in to comment.