示例#1
0
    def configure_main(self):
        # Pass apicula tool options to yosys and nextpnr
        self.edam["tool_options"] = {
            "yosys": {
                "arch": "gowin",
                "output_format": "json",
                "yosys_synth_options": [f"-json {self.name}.json"]
                + self.tool_options.get("yosys_synth_options", []),
                "yosys_as_subtool": True,
                "yosys_template": self.tool_options.get("yosys_template"),
            },
            "nextpnr": {
                "device": self.tool_options.get("device"),
                "nextpnr_options": self.tool_options.get("nextpnr_options", []),
            },
        }

        yosys = Yosys(self.edam, self.work_root)
        yosys.configure()

        nextpnr = Nextpnr(yosys.edam, self.work_root)
        nextpnr.flow_config = {"arch": "gowin"}
        nextpnr.configure()

        # Write Makefile
        commands = EdaCommands()
        commands.commands = yosys.commands

        commands.commands += nextpnr.commands

        # Image generation
        depends = self.name + ".pack"
        targets = self.name + ".fs"
        command = [
            "gowin_pack",
            "-d",
            self.tool_options.get("device"),
            "-o",
            targets,
            depends,
        ]
        commands.add(command, [targets], [depends])

        commands.set_default_target(targets)
        commands.write(os.path.join(self.work_root, "Makefile"))
示例#2
0
    def configure_main(self):
        # Pass trellis tool options to yosys and nextpnr
        self.edam["tool_options"] = {
            "yosys": {
                "arch":
                "nexus",
                "output_format":
                "json",
                "yosys_synth_options":
                self.tool_options.get("yosys_synth_options", []),
                "yosys_as_subtool":
                True,
                "yosys_template":
                self.tool_options.get("yosys_template"),
            },
            "nextpnr": {
                "device": self.tool_options.get("device"),
                "nextpnr_options":
                self.tool_options.get("nextpnr_options", []),
            },
        }

        yosys = Yosys(self.edam, self.work_root)
        yosys.configure()

        nextpnr = Nextpnr(yosys.edam, self.work_root)
        nextpnr.flow_config = {"arch": "nexus"}
        nextpnr.configure()

        # Write Makefile
        commands = EdaCommands()
        commands.commands = yosys.commands

        commands.commands += nextpnr.commands

        # Image generation
        depends = self.name + ".fasm"
        targets = self.name + ".bit"
        command = ["prjoxide", "pack", depends, targets]
        commands.add(command, [targets], [depends])

        commands.set_default_target(self.name + ".bit")
        commands.write(os.path.join(self.work_root, "Makefile"))
示例#3
0
    def configure_main(self):
        # pass mistral tool option to yosys and nextpnr

        self.edam["tool_options"] = {
            "yosys": {
                "arch":
                "intel_alm",
                "output_format":
                "json",
                "yosys_synth_options":
                self.tool_options.get("yosys_synth_options", []),
                "yosys_as_subtool":
                True,
                "yosys_template":
                self.tool_options.get("yosys_template"),
            },
            "nextpnr": {
                "device": self.tool_options.get("device"),
                "nextpnr_options":
                self.tool_options.get("nextpnr_options", []),
            },
        }

        yosys = Yosys(self.edam, self.work_root)
        yosys.configure()

        nextpnr = Nextpnr(yosys.edam, self.work_root)
        nextpnr.flow_config = {"arch": "mistral"}
        nextpnr.configure()

        # Write Makefile
        commands = EdaCommands()

        commands.commands = yosys.commands

        commands.commands += nextpnr.commands

        # Image generation

        commands.set_default_target(self.name + ".rbf")

        commands.write(os.path.join(self.work_root, "Makefile"))
示例#4
0
    def configure_nextpnr(self):
        (src_files, incdirs) = self._get_fileset_files(force_slash=True)
        vendor = self.tool_options.get("vendor")

        # Yosys configuration
        yosys_synth_options = self.tool_options.get("yosys_synth_options", "")
        yosys_template = self.tool_options.get("yosys_template")
        yosys_edam = {
            "files": self.files,
            "name": self.name,
            "toplevel": self.toplevel,
            "parameters": self.parameters,
            "tool_options": {
                "yosys": {
                    "arch": vendor,
                    "output_format": "json",
                    "yosys_synth_options": yosys_synth_options,
                    "yosys_template": yosys_template,
                    "yosys_as_subtool": True,
                }
            },
        }

        yosys = getattr(import_module("edalize.yosys"),
                        "Yosys")(yosys_edam, self.work_root)
        yosys.configure()

        # Nextpnr configuration
        arch = self.tool_options.get("arch")
        if arch not in self.archs:
            logger.error(
                'Missing or invalid "arch" parameter: {} in "tool_options"'.
                format(arch))

        package = self.tool_options.get("package")
        if not package:
            logger.error('Missing required "package" parameter')

        part = self.tool_options.get("part")
        if not part:
            logger.error('Missing required "part" parameter')

        target_family = None
        for family in getattr(self, "fpga_interchange_families"):
            if family in part:
                target_family = family
                break

        if target_family is None and arch == "fpga_interchange":
            logger.error(
                "Couldn't find family for part: {}. Available families: {}".
                format(part,
                       ", ".join(getattr(self, "fpga_interchange_families"))))

        chipdb = None
        device = None
        placement_constraints = []

        for f in src_files:
            if f.file_type in ["bba"]:
                chipdb = f.name
            elif f.file_type in ["device"]:
                device = f.name
            elif f.file_type in ["xdc"]:
                placement_constraints.append(f.name)
            else:
                continue

        if not chipdb:
            logger.error("Missing required chipdb file")

        if placement_constraints == []:
            logger.error("Missing required XDC file(s)")

        if device is None and arch == "fpga_interchange":
            logger.error(
                'Missing required ".device" file for "fpga_interchange" arch')

        nextpnr_options = self.tool_options.get("nextpnr_options", "")
        partname = part + package
        # Strip speedgrade string when using fpga_interchange
        package = package.split("-")[0] if arch == "fpga_interchange" else None

        if "xc7a" in part:
            bitstream_device = "artix7"
        if "xc7z" in part:
            bitstream_device = "zynq7"
        if "xc7k" in part:
            bitstream_device = "kintex7"

        depends = self.name + ".json"
        xdcs = []
        for x in placement_constraints:
            xdcs += ["--xdc", x]

        commands = EdaCommands()
        commands.commands = yosys.commands
        if arch == "fpga_interchange":
            commands.header += """ifndef INTERCHANGE_SCHEMA_PATH
$(error Environment variable INTERCHANGE_SCHEMA_PATH was not found. It should be set to <fpga-interchange-schema path>/interchange)
endif

"""
            targets = self.name + ".netlist"
            command = ["python", "-m", "fpga_interchange.yosys_json"]
            command += ["--schema_dir", "$(INTERCHANGE_SCHEMA_PATH)"]
            command += ["--device", device]
            command += ["--top", self.toplevel]
            command += [depends, targets]
            commands.add(command, [targets], [depends])

            depends = self.name + ".netlist"
            targets = self.name + ".phys"
            command = ["nextpnr-" + arch, "--chipdb", chipdb]
            command += ["--package", package]
            command += xdcs
            command += ["--netlist", depends]
            command += ["--write", self.name + ".routed.json"]
            command += ["--phys", targets]
            command += [nextpnr_options]
            commands.add(command, [targets], [depends])

            depends = self.name + ".phys"
            targets = self.name + ".fasm"
            command = ["python", "-m", "fpga_interchange.fasm_generator"]
            command += ["--schema_dir", "$(INTERCHANGE_SCHEMA_PATH)"]
            command += [
                "--family",
                family,
                device,
                self.name + ".netlist",
                depends,
                targets,
            ]
            commands.add(command, [targets], [depends])
        else:
            targets = self.name + ".fasm"
            command = ["nextpnr-" + arch, "--chipdb", chipdb]
            command += xdcs
            command += ["--json", depends]
            command += ["--write", self.name + ".routed.json"]
            command += ["--fasm", targets]
            command += ["--log", "nextpnr.log"]
            command += [nextpnr_options]
            commands.add(command, [targets], [depends])

        depends = self.name + ".fasm"
        targets = self.name + ".bit"
        command = ["symbiflow_write_bitstream", "-d", bitstream_device]
        command += ["-f", depends, "-p", partname, "-b", targets]
        commands.add(command, [targets], [depends])

        commands.set_default_target(targets)
        commands.write(os.path.join(self.work_root, "Makefile"))
示例#5
0
    def configure_main(self):
        (src_files, incdirs) = self._get_fileset_files()
        synth_out = self.name + "_synth.v"

        device = self.tool_options.get("device")
        if not device:
            raise RuntimeError("Missing required option 'device' for p_r")

        match = re.search("^CCGM1A([1-9]{1,2})$", device)
        if not match:
            raise RuntimeError("{} is not known device name".format(device))

        device_number = match.groups()[0]
        if device_number not in ["1", "2", "4", "9", "16", "25"]:
            raise RuntimeError(
                "Rel. size {} is not unsupported".format(device_number))

        ccf_file = None

        for f in src_files:
            if f.file_type == "CCF":
                if ccf_file:
                    raise RuntimeError(
                        "p_r only supports one ccf file. Found {} and {}".
                        format(ccf_file, f.name))
                else:
                    ccf_file = f.name

        # Pass trellis tool options to yosys
        self.edam["tool_options"] = {
            "yosys": {
                "arch":
                "gatemate",
                "output_format":
                "verilog",
                "output_name":
                synth_out,
                "yosys_synth_options":
                self.tool_options.get("yosys_synth_options", []),
                "yosys_as_subtool":
                True,
                "yosys_template":
                self.tool_options.get("yosys_template"),
            },
        }

        yosys = Yosys(self.edam, self.work_root)
        yosys.configure()

        # Write Makefile
        commands = EdaCommands()
        commands.commands = yosys.commands

        # PnR & image generation
        targets = self.name + "_00.cfg.bit"
        command = [
            "p_r",
            "-A",
            device_number,
            "-i",
            synth_out,
            "-o",
            self.name,
            "-lib",
            "ccag",
            " ".join(self.tool_options.get("p_r_options", "")),
        ]
        if ccf_file is not None:
            command += ["-ccf", ccf_file]
        commands.add(command, [targets], [synth_out])

        commands.set_default_target(targets)
        commands.write(os.path.join(self.work_root, "Makefile"))