from amaranth import * from amaranth.build import * from amaranth.lib.cdc import ResetSynchronizer __all__ = ["SymbiYosysPlatform"] class SymbiYosysPlatform(TemplatedPlatform): """ Required tools: * ``yosys`` * ``sby`` Required tools for VHDL support (experimental): * ``ghdl`` * ``ghdl-yosys-plugin`` Available overrides: * ``sby_opts``: adds extra options for sby (default: "-f"). * ``sby_depth``: depth of the bounded model check in sby script. * ``sby_skip``: number of skipped time steps in sby script. * ``read_verilog_opts``: adds options for the ``read_verilog`` Yosys command. * ``ghdl_opts``: adds options for the ``ghdl`` Yosys command. * ``ghdl_top``: Top-level unit for the ``ghdl`` Yosys command (default: "top"). * ``prep_opts``: adds options for the ``prep`` Yosys command (default: "-flatten -nordff"). * ``script_before_read``: inserts commands before reading input files in Yosys script. * ``script_after_read``: inserts command after reading input files in Yosys script. * ``script_after_synth``: inserts command after ``prep`` in Yosys script. Build products: (TODO) """ toolchain = "oss-cad-suite" required_tools = [ "yosys", "sby", ] file_templates = { **TemplatedPlatform.build_script_templates, "{{name}}.il": r""" # {{autogenerated}} {{emit_rtlil()}} """, "{{name}}.sby": r""" # {{autogenerated}} [options] mode {{get_override("mode")|default("bmc")}} expect pass,fail append 0 depth {{get_override("depth")}} skip {{get_override("skip")}} [engines] smtbmc boolector [files] {% for file in platform.iter_files(".il", ".v", ".sv", ".vhdl") -%} {{file}} {% endfor %} {{name}}.il [script] {% if platform.iter_files(".vhdl")|first is defined -%} plugin -i ghdl {% endif %} {{get_override("script_before_read")|default("# (script_before_read placeholder)")}} {% for file in platform.iter_files(".il") -%} read_ilang {{file}} {% endfor %} {% for file in platform.iter_files(".v", ".sv") -%} read_verilog {{get_override("read_verilog_opts")|default("-sv")}} {{file}} {% endfor %} {% if platform.iter_files(".vhdl")|first is defined -%} ghdl {{get_override("ghdl_opts")|options}} {{platform.iter_files(".vhdl")|join(" ")}} -e {{get_override("ghdl_top")|default("toplevel")}} {% endif %} read_ilang {{name}}.il delete w:$verilog_initial_trigger {{get_override("script_after_read")|default("# (script_after_read placeholder)")}} prep {{get_override("prep_opts")|default("-nordff")}} -top {{name}} {{get_override("script_after_synth")|default("# (script_after_synth placeholder)")}} """, } command_templates = [ r""" {{invoke_tool("sby")}} {{get_override("sby_opts")|default("-f")}} --yosys={{invoke_tool("yosys")}} {{name}}.sby """, ] default_clk = "clk" resources = [ Resource("clk", 0, Pins("clk", dir="i"), Clock(1e6)), ] connectors = [] def create_missing_domain(self, name): if name == "sync": clk_i = self.request(self.default_clk).i rst_i = Const(0) m = Module() m.domains.sync = ClockDomain("sync") m.d.comb += ClockSignal("sync").eq(clk_i) m.submodules.reset_sync = ResetSynchronizer(rst_i, domain="sync") return m