self._clocks[clock] = float(frequency)
def iter_clock_constraints(self):
- return iter(self._clocks.items())
+ # Back-propagate constraints through the input buffer. For clock constraints on pins
+ # (the majority of cases), toolchains work better if the constraint is defined on the pin
+ # and not on the buffered internal net; and if the toolchain is advanced enough that
+ # it considers clock phase and delay of the input buffer, it is *necessary* to define
+ # the constraint on the pin to match the designer's expectation of phase being referenced
+ # to the pin.
+ #
+ # Constraints on nets with no corresponding input pin (e.g. PLL or SERDES outputs) are not
+ # affected.
+ pin_i_to_port = SignalDict()
+ for res, pin, port, attrs in self._ports:
+ if hasattr(pin, "i"):
+ if isinstance(res.ios[0], Pins):
+ pin_i_to_port[pin.i] = port.io
+ elif isinstance(res.ios[0], DiffPairs):
+ pin_i_to_port[pin.i] = port.p
+ else:
+ assert False
+
+ for net_signal, frequency in self._clocks.items():
+ port_signal = pin_i_to_port.get(net_signal)
+ yield net_signal, port_signal, frequency
set_global_assignment -name GENERATE_RBF_FILE ON
""",
"{{name}}.sdc": r"""
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- create_clock -period {{1000000000/frequency}} [get_nets {{signal|hierarchy("|")}}]
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
+ {% else -%}
+ create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("|")}}]
+ {% endif %}
{% endfor %}
""",
"{{name}}.srf": r"""
{% for warning in platform.quartus_suppressed_warnings %}
{ "" "" "" "{{name}}.v" { } { } 0 {{warning}} "" 0 0 "Design Software" 0 -1 0 ""}
{% endfor %}
- """,
+ """,
}
command_templates = [
r"""
{%- for key, value in extras.items() %} {{key}}={{value}}{% endfor %};
{% endif %}
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- FREQUENCY NET "{{signal|hierarchy(".")}}" {{frequency}} HZ;
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ FREQUENCY PORT "{{port_signal.name}}" {{frequency}} HZ;
+ {% else -%}
+ FREQUENCY NET "{{net_signal|hierarchy(".")}}" {{frequency}} HZ;
+ {% endif %}
{% endfor %}
{{get_override("add_preferences")|default("# (add_preferences placeholder)")}}
"""
IOBUF PORT "{{port_name}}"
{%- for key, value in extras.items() %} {{key}}={{value}}{% endfor %};
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- FREQUENCY NET "{{signal|hierarchy("/")}}" {{frequency/1000000}} MHZ;
- {% endfor %}
{{get_override("add_preferences")|default("# (add_preferences placeholder)")}}
""",
"{{name}}.sdc": r"""
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- create_clock -period {{1000000000/frequency}} [get_nets {{signal|hierarchy("/")}}]
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
+ {% else -%}
+ create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
+ {% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
""",
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
set_io {{port_name}} {{pin_name}}
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- set_frequency {{signal|hierarchy(".")}} {{frequency/1000000}}
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ set_frequency {{net_signal|hierarchy(".")}} {{frequency/1000000}}
{% endfor%}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
""",
""",
"{{name}}.sdc": r"""
# {{autogenerated}}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- create_clock -name {{signal.name}} -period {{1000000000/frequency}} [get_nets {{signal|hierarchy("/")}}]
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
+ {% else -%}
+ create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
+ {% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
""",
{%- for key, value in extras.items() %} {{key}}={{value}}{% endfor %};
{% endif %}
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- FREQUENCY NET "{{signal|hierarchy("/")}}" {{frequency/1000000}} MHZ;
- {% endfor %}
{{get_override("add_preferences")|default("# (add_preferences placeholder)")}}
""",
"{{name}}.sdc": r"""
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- create_clock -period {{1000000000/frequency}} [get_nets {{signal|hierarchy("/")}}]
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
+ {% else -%}
+ create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
+ {% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
""",
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name}}]
{% endfor %}
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- create_clock -name {{signal.name}} -period {{1000000000/frequency}} [get_nets {{signal|hierarchy("/")}}]
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
+ {% else -%}
+ create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
+ {% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
"""
NET "{{port_name}}" {{attr_name}}={{attr_value}};
{% endfor %}
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- NET "{{signal|hierarchy("/")}}" TNM_NET="PRD{{signal|hierarchy("/")}}";
- TIMESPEC "TS{{signal|hierarchy("/")}}"=PERIOD "PRD{{signal|hierarchy("/")}}" {{1000000000/frequency}} ns HIGH 50%;
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ NET "{{net_signal|hierarchy("/")}}" TNM_NET="PRD{{net_signal|hierarchy("/")}}";
+ TIMESPEC "TS{{net_signal|hierarchy("/")}}"=PERIOD "PRD{{net_signal|hierarchy("/")}}" {{1000000000/frequency}} ns HIGH 50%;
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
"""
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name}}]
{% endfor %}
{% endfor %}
- {% for signal, frequency in platform.iter_clock_constraints() -%}
- create_clock -name {{signal.name}} -period {{1000000000/frequency}} [get_nets {{signal|hierarchy("/")}}]
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is not none -%}
+ create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
+ {% else -%}
+ create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
+ {% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
"""