+ # Symbiflow templates
+
+ _symbiflow_part_map = {
+ "xc7a35ticsg324-1L": "xc7a35tcsg324-1", # Arty-A7
+ }
+
+ _symbiflow_required_tools = [
+ "synth",
+ "pack",
+ "place",
+ "route",
+ "write_fasm",
+ "write_bitstream"
+ ]
+ _symbiflow_file_templates = {
+ **TemplatedPlatform.build_script_templates,
+ "{{name}}.v": r"""
+ /* {{autogenerated}} */
+ {{emit_verilog()}}
+ """,
+ "{{name}}.debug.v": r"""
+ /* {{autogenerated}} */
+ {{emit_debug_verilog()}}
+ """,
+ "{{name}}.pcf": r"""
+ # {{autogenerated}}
+ {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
+ set_io {{port_name}} {{pin_name}}
+ {% endfor %}
+ """,
+ "{{name}}.xdc": r"""
+ # {{autogenerated}}
+ {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
+ {% for attr_name, attr_value in attrs.items() -%}
+ set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_escape}} }]
+ {% endfor %}
+ {% endfor %}
+ {{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
+ """,
+ "{{name}}.sdc": r"""
+ # {{autogenerated}}
+ {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
+ {% if port_signal is none -%}
+ create_clock -period {{1000000000/frequency}} {{net_signal.name|ascii_escape}}
+ {% endif %}
+ {% endfor %}
+ """
+ }
+ _symbiflow_command_templates = [
+ r"""
+ {{invoke_tool("synth")}}
+ -t {{name}}
+ -v {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} {{file}} {% endfor %} {{name}}.v
+ -p {{platform._symbiflow_part_map.get(platform._part, platform._part)}}
+ -x {{name}}.xdc
+ """,
+ r"""
+ {{invoke_tool("pack")}}
+ -e {{name}}.eblif
+ -P {{platform._symbiflow_part_map.get(platform._part, platform._part)}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("place")}}
+ -e {{name}}.eblif
+ -p {{name}}.pcf
+ -n {{name}}.net
+ -P {{platform._symbiflow_part_map.get(platform._part, platform._part)}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("route")}}
+ -e {{name}}.eblif
+ -P {{platform._symbiflow_part_map.get(platform._part, platform._part)}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("write_fasm")}}
+ -e {{name}}.eblif
+ -P {{platform._symbiflow_part_map.get(platform._part, platform._part)}}
+ """,
+ r"""
+ {{invoke_tool("write_bitstream")}}
+ -f {{name}}.fasm
+ -p {{platform._symbiflow_part_map.get(platform._part, platform._part)}}
+ -b {{name}}.bit
+ """
+ ]
+
+ # Common logic
+
+ def __init__(self, *, toolchain="Vivado"):
+ super().__init__()
+
+ assert toolchain in ("Vivado", "Symbiflow")
+ self.toolchain = toolchain
+
+ @property
+ def required_tools(self):
+ if self.toolchain == "Vivado":
+ return self._vivado_required_tools
+ if self.toolchain == "Symbiflow":
+ return self._symbiflow_required_tools
+ assert False
+
+ @property
+ def file_templates(self):
+ if self.toolchain == "Vivado":
+ return self._vivado_file_templates
+ if self.toolchain == "Symbiflow":
+ return self._symbiflow_file_templates
+ assert False
+
+ @property
+ def command_templates(self):
+ if self.toolchain == "Vivado":
+ return self._vivado_command_templates
+ if self.toolchain == "Symbiflow":
+ return self._symbiflow_command_templates
+ assert False
+