device = abstractproperty()
package = abstractproperty()
speed = abstractproperty()
- grade = None
- required_tools = [
- "yosys",
- "vivado"
- ]
+ required_tools = ["vivado"]
file_templates = {
**TemplatedPlatform.build_script_templates,
"build_{{name}}.sh": r"""
""",
"{{name}}.tcl": r"""
# {{autogenerated}}
- create_project -force -name {{name}} -part {{platform.device}}-{{platform.package}}-{{platform.speed}}{{"-" + platform.grade if platform.grade else ""}}
+ create_project -force -name {{name}} -part {{platform.device}}-{{platform.package}}-{{platform.speed}}
{% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%}
- add_files {{file}}
+ add_files {{file|tcl_escape}}
{% endfor %}
add_files {{name}}.v
read_xdc {{name}}.xdc
{% for file in platform.iter_extra_files(".xdc") -%}
- read_xdc {{file}}
+ read_xdc {{file|tcl_escape}}
{% endfor %}
{{get_override("script_after_read")|default("# (script_after_read placeholder)")}}
synth_design -top {{name}}
"{{name}}.xdc": r"""
# {{autogenerated}}
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
- set_property LOC {{pin_name}} [get_ports {{port_name}}]
+ set_property LOC {{pin_name}} [get_ports {{port_name|tcl_escape}}]
{% for attr_name, attr_value in attrs.items() -%}
- set_property {{attr_name}} {{attr_value}} [get_ports {{port_name}}]
+ set_property {{attr_name}} {{attr_value|tcl_escape}} [get_ports {{port_name|tcl_escape}}]
{% endfor %}
{% endfor %}
{% 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}}]
+ create_clock -name {{port_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}]
{% else -%}
- create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
+ create_clock -name {{net_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}]
{% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
ready = Signal()
m.submodules += Instance("STARTUPE3", o_EOS=ready)
m.domains += ClockDomain("sync", reset_less=self.default_rst is None)
- m.submodules += Instance("BUFGCE", i_CE=ready, i_I=clk_i, o_O=ClockSignal("sync"))
+ # Actually use BUFGCTRL configured as BUFGCE, since using BUFGCE causes sim/synth
+ # mismatches with Vivado 2019.2, and the suggested workaround (SIM_DEVICE parameter)
+ # breaks Vivado 2017.4.
+ m.submodules += Instance("BUFGCTRL",
+ i_I0=clk_i, i_S0=C(1, 1), i_CE0=ready, i_IGNORE0=C(0, 1),
+ i_I1=C(1, 1), i_S1=C(0, 1), i_CE1=C(0, 1), i_IGNORE1=C(1, 1),
+ o_O=ClockSignal("sync")
+ )
if self.default_rst is not None:
m.submodules.reset_sync = ResetSynchronizer(rst_i, domain="sync")
return m
+ def add_clock_constraint(self, clock, frequency):
+ super().add_clock_constraint(clock, frequency)
+ clock.attrs["keep"] = "TRUE"
+
def _get_xdr_buffer(self, m, pin, *, i_invert=False, o_invert=False):
def get_dff(clk, d, q):
# SDR I/O is performed by packing a flip-flop into the pad IOB.