from abc import abstractproperty from ..hdl import * from ..lib.cdc import ResetSynchronizer from ..build import * __all__ = ["QuicklogicPlatform"] class QuicklogicPlatform(TemplatedPlatform): """ Symbiflow toolchain ------------------- Required tools: * ``symbiflow_synth`` * ``symbiflow_pack`` * ``symbiflow_place`` * ``symbiflow_route`` * ``symbiflow_write_fasm`` * ``symbiflow_write_bitstream`` The environment is populated by running the script specified in the environment variable ``NMIGEN_ENV_QLSymbiflow``, if present. Available overrides: * ``add_constraints``: inserts commands in XDC file. """ device = abstractproperty() part = abstractproperty() # Since the QuickLogic version of SymbiFlow toolchain is not upstreamed yet # we should distinguish the QuickLogic version from mainline one. # QuickLogic toolchain: https://github.com/QuickLogic-Corp/quicklogic-fpga-toolchain/releases toolchain = "QLSymbiflow" required_tools = [ "symbiflow_synth", "symbiflow_pack", "symbiflow_place", "symbiflow_route", "symbiflow_write_fasm", "symbiflow_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("symbiflow_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("symbiflow_pack")}} -e {{name}}.eblif -d {{platform.device}} -s {{name}}.sdc """, r""" {{invoke_tool("symbiflow_place")}} -e {{name}}.eblif -d {{platform.device}} -p {{name}}.pcf -n {{name}}.net -P {{platform.part}} -s {{name}}.sdc """, r""" {{invoke_tool("symbiflow_route")}} -e {{name}}.eblif -d {{platform.device}} -s {{name}}.sdc """, r""" {{invoke_tool("symbiflow_write_fasm")}} -e {{name}}.eblif -d {{platform.device}} -s {{name}}.sdc """, r""" {{invoke_tool("symbiflow_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"