示例#1
0
def pnr(netlist, cfgfile, outfile, top="top"):
    _logger.info("Starting Place-and-route")

    with open(cfgfile, "r") as f:
        cfg = yaml.safe_load(f)

    try:
        netlist = Netlist(netlist, top)

        try:
            gal = _devices[cfg["device"]](cfg["mode"])
        except KeyError:
            _logger.error("Supported devices: %s", ",".join(_devices.keys()))
            raise PnrError("Invalid target: {}".format(target))

        gal.pnr(netlist, cfg["pins"])

        _logger.info("Place-and-route succeed")
    except PnrError as exc:
        _logger.error(exc)
        return False

    with open(outfile, "w+") as f:
        _logger.info("Producing JEDEC file to {}".format(outfile))
        gal.write_jedec(f)

    return True
示例#2
0
    def set_registered(self, clock, pins):
        _logger.info("Configure macro cell %s in registered mode (clock: %s)",
                     self.outpad, clock)
        if self.gal_mode != "registered":
            raise PnrError("GAL_DFF can only be synthesized in registered mode"
                           " (current GAL mode: {})".format(self.gal_mode))

        sysclk = None
        for netname, pin in pins.items():
            if pin == 1:
                sysclk = netname

        if clock != sysclk:
            raise PnrError("{} is not mapped to a clock input "
                           "(currently mapped to {} signal)".format(
                               clock, sysclk))
        self.fuse_ac1 = 0
示例#3
0
 def get_driver(self, bit):
     for cell_name, cell in self.top["cells"].items():
         for connection_name, bits in cell["connections"].items():
             if bit in bits and \
                cell["port_directions"][connection_name] == "output":
                 _logger.debug("Found driver for bit %d: %s", bit,
                               cell_name)
                 return cell
     raise PnrError("Cannot find a driver for bit {}".format(bit))
示例#4
0
    def _connect_input(self, netname, pins, table):
        _logger.info("Connecting input %s to macro cell %d", netname,
                     self.outpad)
        try:
            inpad = pins[netname]
        except KeyError:
            raise PnrError("No IO assigned for netname {}".format(netname))

        try:
            index_input = self.inputs.index(inpad)
        except ValueError:
            raise PnrError("Pad {} cannot be assigned as input".format(inpad))
        _logger.debug("Position of netname %s: %d", netname, index_input)

        for i in range(self.depth - int(self.has_oe())):
            idx = (i + int(self.has_oe())) * self.width + (index_input * 2)
            self.fuses_and_array[idx] = table[i * 2] ^ 1
            self.fuses_and_array[idx + 1] = table[i * 2 + 1] ^ 1
示例#5
0
    def configure(self, netlist, bit, pins):
        _logger.info("Configuring macro cell %s", self.outpad)

        self.fuse_xor = 1

        if type(bit) is int:
            driver = netlist.get_driver(bit)

            if driver["type"] == "GAL_DFF":
                clock = netlist.get_netname(driver["connections"]["C"][0])
                self.set_registered(clock, pins)
                driver = netlist.get_driver(driver["connections"]["D"][0])

            if driver["type"] == "GAL_XOR":
                self.invert()
                driver = netlist.get_driver(driver["connections"]["A"][0])

            if driver["type"] == "GAL_SOP":
                if driver["parameters"]["WIDTH"] == 1:
                    upstream = driver["connections"]["I0"][0]
                    if netlist.get_netname(upstream) not in pins.keys():
                        _logger.info("Inverter SOP detected: %s", upstream)
                        self.invert()
                        driver = netlist.get_driver(upstream)

            if driver["type"] == "GAL_SOP":
                self.configure_and_array(netlist, driver, pins)
            else:
                raise PnrError("Unknown cell type: {}".format(driver["type"]))
        elif bit == "1":
            self.invert()
        elif bit != "0":
            raise PnrError("Cannot assign value {} to outpad {}".format(
                bit, self.outpad))

        self.used = True
示例#6
0
    def pnr(self, netlist, pins):
        for netname, pin, direction in netlist.get_ios(pins):
            if direction == "output":
                cell = self.get_cell(pin)
                if cell.used:
                    raise PnrError("Cell {} is already used".format(pin))

                bit = netlist.get_bit(netname)
                cell.configure(netlist, bit, pins)
            else:
                try:
                    cell = self.get_cell(pin)
                except KeyError:
                    pass
                else:
                    cell.configure_as_input()
示例#7
0
    def _get_input_table(self, sop, index):
        sop_table = sop["parameters"]["TABLE"]
        sop_depth = sop["parameters"]["DEPTH"]
        sop_width = sop["parameters"]["WIDTH"]

        if sop_depth > self.get_useable_depth():
            raise PnrError(
                "Pin {}: sum-of-product cannot fit in the macro-cell. "
                "(Depth: {}, Max: {})".format(self.outpad, sop_depth,
                                              self.get_useable_depth()))

        if isinstance(sop_table, str):
            sop_table = int(sop_table, 2)

        table = []
        for i in range(index * 2, self.depth * sop_width * 2, sop_width * 2):
            table.append((sop_table >> (i + 1) & 1))
            table.append((sop_table >> i & 1))

        _logger.debug("Input table %d: %s", index, table)
        return table
示例#8
0
 def get_netname(self, bit):
     for name, netname in self.top["netnames"].items():
         if bit in netname["bits"]:
             return name
     raise PnrError("Cannot find netname for bit {}".format(bit))
示例#9
0
 def get_bit(self, netname):
     bits = self.get_bits(netname)
     if len(bits) != 1:
         raise PnrError("Wire {} must be exactly 1 bit (is {})".format(
             netname, len(bits)))
     return bits[0]