#!/usr/bin/env python3
#
# Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
# SPDX-License-Identifier: Apache-2.0
#

import argparse
import random
import sys

import odb


class DiodeInserter:
    def __init__(
        self,
        block,
        diode_cell,
        diode_pin,
        fake_diode_cell=None,
        side_strategy="source",
        short_span=0,
        port_protect=[],
        verbose=False,
    ):
        self.block = block
        self.verbose = verbose

        self.diode_cell = diode_cell
        self.diode_pin = diode_pin
        self.fake_diode_cell = fake_diode_cell
        self.side_strategy = side_strategy
        self.short_span = short_span
        self.port_protect = port_protect

        self.true_diode_master = block.getDataBase().findMaster(diode_cell)
        self.fake_diode_master = (
            block.getDataBase().findMaster(fake_diode_cell)
            if (fake_diode_cell is not None)
            else None
        )
        if not self.check():
            raise RuntimeError("True and Fake diodes are inconsistent")

        self.diode_master = self.fake_diode_master or self.true_diode_master
        self.diode_site = self.true_diode_master.getSite().getConstName()

        self.inserted = {}

    def check(self):
        if self.fake_diode_master is None:
            return True

        tm = self.true_diode_master
        fm = self.fake_diode_master

        if fm.getSite() is None:
            self.error("[!] Fake diode cell missing SITE attribute")
        else:
            if fm.getSite().getConstName() != tm.getSite().getConstName():
                return False

        if fm.getWidth() != tm.getWidth():
            return False
        if fm.getHeight() != tm.getHeight():
            return False

        return True

    def debug(self, msg):
        if self.verbose:
            print(msg, file=sys.stderr)

    def error(self, msg):
        print(msg, file=sys.stderr)

    def net_source(self, net):
        # See if it's an input pad
        for bt in net.getBTerms():
            if bt.getIoType() != "INPUT":
                continue
            good, x, y = bt.getFirstPinLocation()
            if good:
                return (x, y)

        # Or maybe output of a cell
        # x = odb.new_int(0)
        # y = odb.new_int(0)

        for it in net.getITerms():
            if not it.isOutputSignal():
                continue
            found, x, y = it.getAvgXY()
            if found:
                return x, y

        # Nothing found
        return None

    def net_from_pin(self, net, io_types=None):
        for bt in net.getBTerms():
            if (io_types is None) or (bt.getIoType() in io_types):
                return True
        return False

    def net_has_diode(self, net):
        for it in net.getITerms():
            cell_type = it.getInst().getMaster().getConstName()
            cell_pin = it.getMTerm().getConstName()
            if (cell_type == self.diode_cell) and (cell_pin == self.diode_pin):
                return True
        else:
            return False

    def net_span(self, net):
        xs = []
        ys = []

        for bt in net.getBTerms():
            good, x, y = bt.getFirstPinLocation()
            if good:
                xs.append(x)
                ys.append(y)

        for it in net.getITerms():
            x, y = self.pin_position(it)
            xs.append(x)
            ys.append(y)

        if len(xs) == 0:
            return 0

        return (max(ys) - min(ys)) + (max(xs) - min(xs))

    def pin_position(self, it):
        # px = odb.new_int(0)
        # py = odb.new_int(0)

        found, px, py = it.getAvgXY()
        if found:
            # Got it
            return px, py
        else:
            # Failed, use the center coordinate of the instance as fall back
            return it.getInst().getLocation()

    def place_diode_stdcell(self, it, px, py, src_pos=None):
        # Get information about the instance
        inst_name = it.getInst().getConstName()
        inst_width = it.getInst().getMaster().getWidth()
        inst_pos = it.getInst().getLocation()
        inst_ori = it.getInst().getOrient()

        # Is the pin left-ish, center-ish or right-ish ?
        pos = None

        if self.side_strategy == "source":
            # Always be on the side of the source
            if src_pos is not None:
                pos = "l" if (src_pos[0] < inst_pos[0]) else "r"

        elif self.side_strategy == "pin":
            # Always be on the side of the pin
            pos = "l" if (px < (inst_pos[0] + inst_width // 2)) else "r"

        elif self.side_strategy == "balanced":
            # If pin is really on the side, use that, else use source side
            th_left = int(inst_pos[0] + inst_width * 0.25)
            th_right = int(inst_pos[0] + inst_width * 0.75)

            if px < th_left:
                pos = "l"
            elif px > th_right:
                pos = "r"
            elif src_pos is not None:
                # Sort of middle, so put it on the side where signal is coming from
                pos = "l" if (src_pos[0] < inst_pos[0]) else "r"

        if pos is None:
            # Coin toss ...
            pos = "l" if (random.random() > 0.5) else "r"

        # X position
        dw = self.diode_master.getWidth()

        if pos == "l":
            dx = inst_pos[0] - dw * (1 + self.inserted.get((inst_name, "l"), 0))
        else:
            dx = inst_pos[0] + inst_width + dw * self.inserted.get((inst_name, "r"), 0)

        # Record insertion
        self.inserted[(inst_name, pos)] = self.inserted.get((inst_name, pos), 0) + 1

        # Done
        return dx, inst_pos[1], inst_ori

    def place_diode_macro(self, it, px, py, src_pos=None):
        # Scan all rows to see how close we can get to the point
        best = None

        for row in self.block.getRows():
            rbb = row.getBBox()

            dx = max(min(rbb.xMax(), px), rbb.xMin())
            dy = rbb.yMin()
            do = row.getOrient()

            d = abs(px - dx) + abs(py - dy)

            if (best is None) or (best[0] > d):
                best = (d, dx, dy, do)

        return best[1:]

    def insert_diode(self, it, src_pos, force_true=False):
        # Get information about the instance
        inst = it.getInst()
        inst_name = inst.getConstName()
        inst_site = (
            inst.getMaster().getSite().getConstName()
            if (inst.getMaster().getSite() is not None)
            else None
        )

        # Find where the pin is
        px, py = self.pin_position(it)

        # Apply standard cell or macro placement ?
        if inst_site == self.diode_site:
            dx, dy, do = self.place_diode_stdcell(it, px, py, src_pos)
        else:
            dx, dy, do = self.place_diode_macro(it, px, py, src_pos)

        # Insert instance and wire it up
        diode_inst_name = "ANTENNA_" + inst_name + "_" + it.getMTerm().getConstName()
        diode_master = self.true_diode_master if force_true else self.diode_master

        diode_inst = odb.dbInst_create(self.block, diode_master, diode_inst_name)

        diode_inst.setOrient(do)
        diode_inst.setLocation(dx, dy)
        diode_inst.setPlacementStatus("PLACED")

        ait = diode_inst.findITerm(self.diode_pin)
        ait.connect(it.getNet())

    def execute(self):
        # Scan all nets
        for net in self.block.getNets():
            # Skip special nets
            if net.isSpecial():
                self.debug(f"[d] Skipping special net {net.getConstName():s}")
                continue

            # Check if we already have diode on the net
            # if yes, then we assume that the user took care of that net manually
            if self.net_has_diode(net):
                self.debug(
                    f"[d] Skipping manually protected net {net.getConstName():s}"
                )
                continue

            # Find signal source (first one found ...)
            src_pos = self.net_source(net)

            # Is this an IO we need to protect
            io_protect = self.net_from_pin(net, io_types=self.port_protect)
            if io_protect:
                self.debug(
                    f"[d] Forcing protection diode on net  {net.getConstName():s}"
                )

            # Determine the span of the signal and skip small internal nets
            span = self.net_span(net)
            if (span < self.short_span) and not io_protect:
                self.debug(f"[d] Skipping small net {net.getConstName():s} ({span:d})")
                continue

            # Scan all internal terminals
            for it in net.getITerms():
                if it.isInputSignal():
                    self.insert_diode(it, src_pos, force_true=io_protect)


# Arguments
parser = argparse.ArgumentParser(description="Diode Insertion script")

parser.add_argument(
    "--lef",
    "-l",
    nargs="+",
    type=str,
    default=None,
    required=True,
    help="Input LEF file(s)",
)

parser.add_argument(
    "--input-def",
    "-id",
    required=True,
    help="DEF view of the design that needs to have diodes inserted",
)

parser.add_argument("--output-def", "-o", required=True, help="Output DEF file")

parser.add_argument(
    "--verbose",
    "-v",
    action="store_true",
    default=False,
    help="Enable verbose debug output",
)

parser.add_argument(
    "--diode-cell",
    "-c",
    default="sky130_fd_sc_hd__diode_2",
    help="Name of the cell to use as diode",
)

parser.add_argument(
    "--fake-diode-cell", "-f", help="Name of the cell to use as fake diode"
)

parser.add_argument(
    "--diode-pin", "-p", default="DIODE", help="Name of the pin to use on diode cells"
)

parser.add_argument(
    "--side-strategy",
    choices=["source", "pin", "balanced", "random"],
    default="source",
    help="Strategy to select if placing diode left/right of the cell",
)

parser.add_argument(
    "--short-span",
    "-s",
    default=90000,
    type=int,
    help='Maximum span of a net to be considered "short" and not needing a diode',
)

parser.add_argument(
    "--port-protect",
    choices=["none", "in", "out", "both"],
    default="in",
    help="Always place a true diode on nets connected to selected ports",
)


args = parser.parse_args()
input_lef_file_names = args.lef
input_def_file_name = args.input_def
output_def_file_name = args.output_def

# Load
db_design = odb.dbDatabase.create()

for lef in input_lef_file_names:
    odb.read_lef(db_design, lef)
odb.read_def(db_design, input_def_file_name)

chip_design = db_design.getChip()
block_design = chip_design.getBlock()
top_design_name = block_design.getConstName()
print("Design name:", top_design_name)


pp_val = {
    "none": [],
    "in": ["INPUT"],
    "out": ["OUTPUT"],
    "both": ["INPUT", "OUTPUT"],
}

di = DiodeInserter(
    block_design,
    diode_cell=args.diode_cell,
    diode_pin=args.diode_pin,
    fake_diode_cell=args.fake_diode_cell,
    side_strategy=args.side_strategy,
    short_span=args.short_span,
    port_protect=pp_val[args.port_protect],
    verbose=args.verbose,
)
di.execute()

print("Inserted", len(di.inserted), "diodes.")

# Write result
odb.write_def(block_design, output_def_file_name)
