--- /dev/null
+from abc import abstractproperty
+
+from ..hdl import *
+from ..lib.cdc import ResetSynchronizer
+from ..build import *
+
+
+__all__ = ["QuicklogicPlatform"]
+
+
+class QuicklogicPlatform(TemplatedPlatform):
+ """
+ Symbiflow toolchain
+ -------------------
+ Required tools:
+ * ``synth``
+ * ``pack``
+ * ``place``
+ * ``route``
+ * ``write_fasm``
+ * ``write_bitstream``
+ The environment is populated by running the script specified in the environment variable
+ ``NMIGEN_ENV_Quicklogic``, if present.
+ Available overrides:
+ * ``add_constraints``: inserts commands in XDC file.
+ """
+
+ device = abstractproperty()
+ part = abstractproperty()
+
+ required_tools = [
+ "synth",
+ "pack",
+ "place",
+ "route",
+ "write_fasm",
+ "write_bitstream"
+ ]
+ 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 not none -%}
+ create_clock -period {{100000000/frequency}} {{port_signal.name|ascii_escape}}
+ {% endif %}
+ {% endfor %}
+ """
+ }
+ command_templates = [
+ r"""
+ {{invoke_tool("synth")}}
+ -t {{name}}
+ -v {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} {{file}} {% endfor %} {{name}}.v
+ -d {{platform.device}}
+ -p {{name}}.pcf
+ -P {{platform.part}}
+ -x {{name}}.xdc
+ """,
+ r"""
+ {{invoke_tool("pack")}}
+ -e {{name}}.eblif
+ -d {{platform.device}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("place")}}
+ -e {{name}}.eblif
+ -d {{platform.device}}
+ -p {{name}}.pcf
+ -n {{name}}.net
+ -P {{platform.part}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("route")}}
+ -e {{name}}.eblif
+ -d {{platform.device}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("write_fasm")}}
+ -e {{name}}.eblif
+ -d {{platform.device}}
+ -s {{name}}.sdc
+ """,
+ r"""
+ {{invoke_tool("write_bitstream")}}
+ -f {{name}}.fasm
+ -d {{platform.device}}
+ -P {{platform.part}}
+ -b {{name}}.bit
+ """
+ ]
+
+ # Common logic
+
+ def __init__(self, *):
+ super().__init__()
+
+ def add_clock_constraint(self, clock, frequency):
+ super().add_clock_constraint(clock, frequency)
+ clock.attrs["keep"] = "TRUE"