class IntelPlatform(TemplatedPlatform):
"""
+ Quartus toolchain
+ -----------------
+
Required tools:
* ``quartus_map``
* ``quartus_fit``
* ``*.rpt``: toolchain reports.
* ``{{name}}.sof``: bitstream as SRAM object file.
* ``{{name}}.rbf``: bitstream as raw binary file.
+
+
+ Mistral toolchain
+ -----------------
+
+ Required tools:
+ * ``yosys``
+ * ``nextpnr-mistral``
+
+ The environment is populated by running the script specified in the environment variable
+ ``NMIGEN_ENV_Mistral``, if present.
+
+ * ``verbose``: enables logging of informational messages to standard error.
+ * ``read_verilog_opts``: adds options for ``read_verilog`` Yosys command.
+ * ``synth_opts``: adds options for ``synth_intel_alm`` Yosys command.
+ * ``script_after_read``: inserts commands after ``read_ilang`` in Yosys script.
+ * ``script_after_synth``: inserts commands after ``synth_intel_alm`` in Yosys script.
+ * ``yosys_opts``: adds extra options for ``yosys``.
+ * ``nextpnr_opts``: adds extra options for ``nextpnr-mistral``.
"""
- toolchain = "Quartus"
+ toolchain = None # selected when creating platform
device = abstractproperty()
package = abstractproperty()
speed = abstractproperty()
suffix = ""
+ # Quartus templates
+
quartus_suppressed_warnings = [
10264, # All case item expressions in this case statement are onehot
10270, # Incomplete Verilog case statement has no default case item
292013, # Feature is only available with a valid subscription license
]
- required_tools = [
+ quartus_required_tools = [
"quartus_map",
"quartus_fit",
"quartus_asm",
"quartus_sta",
]
- file_templates = {
+ quartus_file_templates = {
**TemplatedPlatform.build_script_templates,
"build_{{name}}.sh": r"""
# {{autogenerated}}
{% endfor %}
""",
}
- command_templates = [
+ quartus_command_templates = [
r"""
{{invoke_tool("quartus_map")}}
{{get_override("quartus_map_opts")|options}}
""",
]
+
+ # Mistral templates
+
+ mistral_required_tools = [
+ "yosys",
+ "nextpnr-mistral"
+ ]
+ mistral_file_templates = {
+ **TemplatedPlatform.build_script_templates,
+ "{{name}}.il": r"""
+ # {{autogenerated}}
+ {{emit_rtlil()}}
+ """,
+ "{{name}}.debug.v": r"""
+ /* {{autogenerated}} */
+ {{emit_debug_verilog()}}
+ """,
+ "{{name}}.ys": r"""
+ # {{autogenerated}}
+ {% for file in platform.iter_files(".v") -%}
+ read_verilog {{get_override("read_verilog_opts")|options}} {{file}}
+ {% endfor %}
+ {% for file in platform.iter_files(".sv") -%}
+ read_verilog -sv {{get_override("read_verilog_opts")|options}} {{file}}
+ {% endfor %}
+ {% for file in platform.iter_files(".il") -%}
+ read_ilang {{file}}
+ {% endfor %}
+ read_ilang {{name}}.il
+ delete w:$verilog_initial_trigger
+ {{get_override("script_after_read")|default("# (script_after_read placeholder)")}}
+ synth_intel_alm {{get_override("synth_opts")|options}} -top {{name}}
+ {{get_override("script_after_synth")|default("# (script_after_synth placeholder)")}}
+ write_json {{name}}.json
+ """,
+ "{{name}}.qsf": r"""
+ # {{autogenerated}}
+ {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
+ set_location_assignment -to {{port_name|tcl_quote}} PIN_{{pin_name}}
+ {% for key, value in attrs.items() -%}
+ set_instance_assignment -to {{port_name|tcl_quote}} -name {{key}} {{value|tcl_quote}}
+ {% endfor %}
+ {% endfor %}
+ """,
+
+ }
+ mistral_command_templates = [
+ r"""
+ {{invoke_tool("yosys")}}
+ {{quiet("-q")}}
+ {{get_override("yosys_opts")|options}}
+ -l {{name}}.rpt
+ {{name}}.ys
+ """,
+ r"""
+ {{invoke_tool("nextpnr-mistral")}}
+ {{quiet("--quiet")}}
+ {{get_override("nextpnr_opts")|options}}
+ --log {{name}}.tim
+ --device {{platform.device}}{{platform.package}}{{platform.speed}}{{platform.suffix}}
+ --json {{name}}.json
+ --qsf {{name}}.qsf
+ --rbf {{name}}.rbf
+ """
+ ]
+
+ # Common logic
+
+ def __init__(self, *, toolchain="Quartus"):
+ super().__init__()
+
+ assert toolchain in ("Quartus", "Mistral")
+ self.toolchain = toolchain
+
+ @property
+ def required_tools(self):
+ if self.toolchain == "Quartus":
+ return self.quartus_required_tools
+ if self.toolchain == "Mistral":
+ return self.mistral_required_tools
+ assert False
+
+ @property
+ def file_templates(self):
+ if self.toolchain == "Quartus":
+ return self.quartus_file_templates
+ if self.toolchain == "Mistral":
+ return self.mistral_file_templates
+ assert False
+
+ @property
+ def command_templates(self):
+ if self.toolchain == "Quartus":
+ return self.quartus_command_templates
+ if self.toolchain == "Mistral":
+ return self.mistral_command_templates
+ assert False
+
def add_clock_constraint(self, clock, frequency):
super().add_clock_constraint(clock, frequency)
clock.attrs["keep"] = "true"