From 23f71424772bd05f1e9b302aa38fe85aa5ee1505 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Thu, 14 Oct 2021 18:02:22 +0200 Subject: [PATCH] vendor.intel: add Mistral toolchain support. --- nmigen/vendor/intel.py | 130 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 4 deletions(-) diff --git a/nmigen/vendor/intel.py b/nmigen/vendor/intel.py index e72a082..b786393 100644 --- a/nmigen/vendor/intel.py +++ b/nmigen/vendor/intel.py @@ -9,6 +9,9 @@ __all__ = ["IntelPlatform"] class IntelPlatform(TemplatedPlatform): """ + Quartus toolchain + ----------------- + Required tools: * ``quartus_map`` * ``quartus_fit`` @@ -31,15 +34,36 @@ class IntelPlatform(TemplatedPlatform): * ``*.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 @@ -51,14 +75,14 @@ class IntelPlatform(TemplatedPlatform): 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}} @@ -124,7 +148,7 @@ class IntelPlatform(TemplatedPlatform): {% endfor %} """, } - command_templates = [ + quartus_command_templates = [ r""" {{invoke_tool("quartus_map")}} {{get_override("quartus_map_opts")|options}} @@ -147,6 +171,104 @@ class IntelPlatform(TemplatedPlatform): """, ] + + # 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" -- 2.30.2