diff --git a/hacks/patch/resizer.patch b/hacks/patch/resizer.patch
new file mode 100644
index 0000000..44e2796
--- /dev/null
+++ b/hacks/patch/resizer.patch
@@ -0,0 +1,29 @@
+diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc
+index b57fce674..cac938c44 100644
+--- a/src/rsz/src/Resizer.cc
++++ b/src/rsz/src/Resizer.cc
+@@ -1685,9 +1685,11 @@ Resizer::resizeToTargetSlew(const Pin *drvr_pin,
+     ensureWireParasitic(drvr_pin);
+     // Includes net parasitic capacitance.
+     float load_cap = graph_delay_calc_->loadCap(drvr_pin, tgt_slew_dcalc_ap_);
+-    if (load_cap > 0.0) {
++    // DINESH-A: delay cells resize disabled
++    if (load_cap > 0.00 && (strncmp(cell->name(),"sky130_fd_sc_hd__clkdlybuf4s15_2",26) != 0)) {
+       LibertyCell *target_cell = findTargetCell(cell, load_cap, revisiting_inst);
+       if (target_cell != cell) {
++        //printf("Dinesh-A: Resizing : %s => %s %s Load_cap: %f \n",sdc_network_->pathName(drvr_pin),cell->name(),target_cell->name(),load_cap);
+         debugPrint(logger_, RSZ, "resize", 2, "{} {} -> {}",
+                    sdc_network_->pathName(drvr_pin),
+                    cell->name(),
+@@ -2500,8 +2502,10 @@ Resizer::repairSetup(PathRef &path,
+         prev_drive = 0.0;
+       LibertyCell *upsize = upsizeCell(in_port, drvr_port, load_cap,
+                                        prev_drive, dcalc_ap);
+-      if (upsize) {
++      // DINESH-A: delay cells resize disabled
++      if (upsize && (strncmp(drvr_port->libertyCell()->name(),"sky130_fd_sc_hd__clkdlybuf4s15_2",26) != 0)) {
+         Instance *drvr = network_->instance(drvr_pin);
++	//printf("Dinesh-A: Upsizing the cells: %s %s %s\n",network_->pathName(drvr_pin),drvr_port->libertyCell()->name(),upsize->name());
+         debugPrint(logger_, RSZ, "repair_setup", 2, "resize {} {} -> {}",
+                    network_->pathName(drvr_pin),
+                    drvr_port->libertyCell()->name(),
diff --git a/hacks/patch/scan_swap.patch b/hacks/patch/scan_swap.patch
new file mode 100644
index 0000000..41d98b7
--- /dev/null
+++ b/hacks/patch/scan_swap.patch
@@ -0,0 +1,60 @@
+diff --git a/src/sta/network/ConcreteNetwork.cc b/src/sta/network/ConcreteNetwork.cc
+index 6f8b842..8096f2e 100644
+--- a/src/sta/network/ConcreteNetwork.cc
++++ b/src/sta/network/ConcreteNetwork.cc
+@@ -1180,11 +1180,14 @@ ConcreteNetwork::replaceCell(Instance *inst,
+   ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+   int port_count = ccell->portBitCount();
+   ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
++  // Port count picked from Instance instead of Target cells-Dinesh A
++  ConcreteCell *instcell = reinterpret_cast<ConcreteCell*>(cinst->cell());
++  int inst_port_count = instcell->portBitCount();
+   ConcretePin **pins = cinst->pins_;
+   ConcretePin **rpins = new ConcretePin*[port_count];
+-  for (int i = 0; i < port_count; i++)
+-    rpins[i] = nullptr;
+-  for (int i = 0; i < port_count; i++) {
++  for (int i = 0; i < port_count; i++) 
++    rpins[i] = pins[inst_port_count-1];
++  for (int i = 0; i < inst_port_count; i++) {
+     ConcretePin *cpin = pins[i];
+     if (cpin) {
+       ConcretePort *pin_cport = reinterpret_cast<ConcretePort*>(cpin->port());
+diff --git a/src/sta/tcl/NetworkEdit.tcl b/src/sta/tcl/NetworkEdit.tcl
+index 5ce616b..bdd4057 100644
+--- a/src/sta/tcl/NetworkEdit.tcl
++++ b/src/sta/tcl/NetworkEdit.tcl
+@@ -236,6 +236,21 @@ proc replace_cell { instance lib_cell } {
+   }
+ }
+ 
++proc replace_to_scan_cell { instance } {
++  set inst [get_instance_error "instance" $instance]
++  set inst_cell [get_full_name [$inst liberty_cell]]
++  #Target scan cell __d to __sd
++  #example sky130_fd_sc_hd__dfrtp_2 to sky130_fd_sc_hd__sdfrtp_2
++  set inst_scell [regsub -all "__d" $inst_cell "__sd"]
++  puts "Info: Scan Swapping => Instance:$instance From:$inst_cell to:$inst_scell";
++  if { $inst_cell == "NULL"} {
++    return 0
++  }
++  set scell [get_lib_cell_warn "lib_cell" $inst_scell]
++  replace_cell_cmd $inst $scell
++  return 1
++}
++
+ proc path_regexp {} {
+   global hierarchy_separator
+   set id_regexp "\[^${hierarchy_separator}\]+"
+diff --git a/src/sta/tcl/Sta.tcl b/src/sta/tcl/Sta.tcl
+index f3de994..a6e8e34 100644
+--- a/src/sta/tcl/Sta.tcl
++++ b/src/sta/tcl/Sta.tcl
+@@ -623,6 +623,7 @@ define_cmd_args "make_instance" {inst_path lib_cell}
+ define_cmd_args "make_net" {}
+ 
+ define_cmd_args "replace_cell" {instance lib_cell}
++define_cmd_args "replace_to_scan_cell" {instance}
+ 
+ define_cmd_args "insert_buffer" {buffer_name buffer_cell net load_pins\
+ 				       buffer_out_net_name}
diff --git a/hacks/src/OpenROAD/Resizer.cc b/hacks/src/OpenROAD/Resizer.cc
new file mode 100644
index 0000000..a339071
--- /dev/null
+++ b/hacks/src/OpenROAD/Resizer.cc
@@ -0,0 +1,4095 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2019, The Regents of the University of California
+// All rights reserved.
+//
+// BSD 3-Clause License
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this
+//   list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// * Neither the name of the copyright holder nor the names of its
+//   contributors may be used to endorse or promote products derived from
+//   this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "rsz/Resizer.hh"
+
+#include "rsz/SteinerTree.hh"
+
+#include "ord/OpenRoad.hh"
+#include "gui/gui.h"
+#include "utl/Logger.h"
+
+#include "sta/Report.hh"
+#include "sta/FuncExpr.hh"
+#include "sta/PortDirection.hh"
+#include "sta/TimingRole.hh"
+#include "sta/Units.hh"
+#include "sta/Liberty.hh"
+#include "sta/TimingArc.hh"
+#include "sta/TimingModel.hh"
+#include "sta/Network.hh"
+#include "sta/Graph.hh"
+#include "sta/DcalcAnalysisPt.hh"
+#include "sta/ArcDelayCalc.hh"
+#include "sta/GraphDelayCalc.hh"
+#include "sta/Parasitics.hh"
+#include "sta/Sdc.hh"
+#include "sta/InputDrive.hh"
+#include "sta/Corner.hh"
+#include "sta/PathVertex.hh"
+#include "sta/SearchPred.hh"
+#include "sta/Bfs.hh"
+#include "sta/Search.hh"
+#include "sta/PathRef.hh"
+#include "sta/PathExpanded.hh"
+#include "sta/StaMain.hh"
+#include "sta/Fuzzy.hh"
+
+// http://vlsicad.eecs.umich.edu/BK/Slots/cache/dropzone.tamu.edu/~zhuoli/GSRC/fast_buffer_insertion.html
+
+namespace sta {
+extern const char *rsz_tcl_inits[];
+}
+
+namespace rsz {
+
+using std::abs;
+using std::min;
+using std::max;
+using std::string;
+using std::to_string;
+using std::vector;
+using std::map;
+using std::pair;
+using std::sqrt;
+
+using utl::RSZ;
+using ord::closestPtInRect;
+
+using odb::dbInst;
+using odb::dbPlacementStatus;
+using odb::Rect;
+using odb::dbOrientType;
+using odb::dbMPin;
+using odb::dbBox;
+using odb::dbMasterType;
+
+using sta::evalTclInit;
+using sta::makeBlockSta;
+using sta::Level;
+using sta::stringLess;
+using sta::Network;
+using sta::NetworkEdit;
+using sta::NetPinIterator;
+using sta::NetConnectedPinIterator;
+using sta::InstancePinIterator;
+using sta::LeafInstanceIterator;
+using sta::LibertyLibraryIterator;
+using sta::LibertyCellIterator;
+using sta::LibertyCellTimingArcSetIterator;
+using sta::TimingArcSet;
+using sta::TimingArcSetArcIterator;
+using sta::TimingArcSetSeq;
+using sta::GateTimingModel;
+using sta::TimingRole;
+using sta::FuncExpr;
+using sta::Term;
+using sta::Port;
+using sta::PinSeq;
+using sta::NetIterator;
+using sta::PinConnectedPinIterator;
+using sta::FindNetDrvrLoads;;
+using sta::VertexIterator;
+using sta::VertexOutEdgeIterator;
+using sta::Edge;
+using sta::Search;
+using sta::SearchPredNonReg2;
+using sta::ClkArrivalSearchPred;
+using sta::BfsBkwdIterator;
+using sta::BfsFwdIterator;
+using sta::BfsIndex;
+using sta::Clock;
+using sta::PathExpanded;
+using sta::INF;
+using sta::fuzzyEqual;
+using sta::fuzzyLess;
+using sta::fuzzyLessEqual;
+using sta::fuzzyGreater;
+using sta::fuzzyGreaterEqual;
+using sta::delayInf;
+using sta::stringPrint;
+using sta::Unit;
+using sta::ArcDelayCalc;
+using sta::Corners;
+using sta::InputDrive;
+
+extern "C" {
+extern int Rsz_Init(Tcl_Interp *interp);
+}
+
+Resizer::Resizer() :
+  StaState(),
+  wire_signal_res_(0.0),
+  wire_signal_cap_(0.0),
+  wire_clk_res_(0.0),
+  wire_clk_cap_(0.0),
+  max_area_(0.0),
+  openroad_(nullptr),
+  logger_(nullptr),
+  gui_(nullptr),
+  sta_(nullptr),
+  db_network_(nullptr),
+  db_(nullptr),
+  block_(nullptr),
+  core_exists_(false),
+  parasitics_src_(ParasiticsSrc::none),
+  design_area_(0.0),
+  max_(MinMax::max()),
+  buffer_lowest_drive_(nullptr),
+  buffer_med_drive_(nullptr),
+  buffer_highest_drive_(nullptr),
+  target_load_map_(nullptr),
+  level_drvr_vertices_valid_(false),
+  tgt_slews_{0.0, 0.0},
+  tgt_slew_corner_(nullptr),
+  tgt_slew_dcalc_ap_(nullptr),
+  unique_net_index_(1),
+  unique_inst_index_(1),
+  resize_count_(0),
+  inserted_buffer_count_(0),
+  max_wire_length_(0),
+  steiner_renderer_(nullptr),
+  rebuffer_net_count_(0)
+{
+}
+
+void
+Resizer::init(OpenRoad *openroad,
+              Tcl_Interp *interp,
+              Logger *logger,
+              Gui *gui,
+              dbDatabase *db,
+              dbSta *sta,
+              SteinerTreeBuilder *stt_builder,
+              GlobalRouter *global_router)
+{
+  openroad_ = openroad;
+  logger_ = logger;
+  gui_ = gui;
+  db_ = db;
+  block_ = nullptr;
+  sta_ = sta;
+  stt_builder_ = stt_builder;
+  global_router_ = global_router;
+  incr_groute_ = nullptr;
+  db_network_ = sta->getDbNetwork();
+  copyState(sta);
+  // Define swig TCL commands.
+  Rsz_Init(interp);
+  // Eval encoded sta TCL sources.
+  evalTclInit(interp, sta::rsz_tcl_inits);
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::coreArea() const
+{
+  return dbuToMeters(core_.dx()) * dbuToMeters(core_.dy());
+}
+
+double
+Resizer::utilization()
+{
+  ensureBlock();
+  ensureDesignArea();
+  double core_area = coreArea();
+  if (core_area > 0.0)
+    return design_area_ / core_area;
+  else
+    return 1.0;
+}
+
+double
+Resizer::maxArea() const
+{
+  return max_area_;
+}
+
+////////////////////////////////////////////////////////////////
+
+class VertexLevelLess
+{
+public:
+  VertexLevelLess(const Network *network);
+  bool operator()(const Vertex *vertex1,
+                  const Vertex *vertex2) const;
+
+protected:
+  const Network *network_;
+};
+
+VertexLevelLess::VertexLevelLess(const Network *network) :
+  network_(network)
+{
+}
+
+bool
+VertexLevelLess::operator()(const Vertex *vertex1,
+                            const Vertex *vertex2) const
+{
+  Level level1 = vertex1->level();
+  Level level2 = vertex2->level();
+  return (level1 < level2)
+    || (level1 == level2
+        // Break ties for stable results.
+        && stringLess(network_->pathName(vertex1->pin()),
+                      network_->pathName(vertex2->pin())));
+}
+
+
+////////////////////////////////////////////////////////////////
+
+// block_ indicates core_, design_area_, db_network_ etc valid.
+void
+Resizer::ensureBlock()
+{
+  // block_ indicates core_, design_area_
+  if (block_ == nullptr) {
+    block_ = db_->getChip()->getBlock();
+    block_->getCoreArea(core_);
+    core_exists_ = !(core_.xMin() == 0
+                     && core_.xMax() == 0
+                     && core_.yMin() == 0
+                     && core_.yMax() == 0);
+  }
+}
+
+void
+Resizer::init()
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+  ensureBlock();
+  ensureDesignArea();
+  ensureLevelDrvrVertices();
+  sta_->ensureClkNetwork();
+}
+
+void
+Resizer::removeBuffers()
+{
+  ensureBlock();
+  db_network_ = sta_->getDbNetwork();
+  // Disable incremental timing.
+  graph_delay_calc_->delaysInvalid();
+  search_->arrivalsInvalid();
+
+  int remove_count = 0;
+  for (dbInst *inst : block_->getInsts()) {
+    LibertyCell *lib_cell = db_network_->libertyCell(inst);
+    if (lib_cell && lib_cell->isBuffer()) {
+      Instance *buffer = db_network_->dbToSta(inst);
+      // Do not remove buffers connected to input/output ports
+      // because verilog netlists use the net name for the port.
+      if (!bufferBetweenPorts(buffer)) {
+        removeBuffer(buffer);
+        remove_count++;
+      }
+    }
+  }
+  level_drvr_vertices_valid_ = false;
+  logger_->info(RSZ, 26, "Removed {} buffers.", remove_count);
+}
+
+bool
+Resizer::bufferBetweenPorts(Instance *buffer)
+{
+  LibertyCell *lib_cell = network_->libertyCell(buffer);
+  LibertyPort *in_port, *out_port;
+  lib_cell->bufferPorts(in_port, out_port);
+  Pin *in_pin = db_network_->findPin(buffer, in_port);
+  Pin *out_pin = db_network_->findPin(buffer, out_port);
+  Net *in_net = db_network_->net(in_pin);
+  Net *out_net = db_network_->net(out_pin);
+  bool in_net_ports = hasPort(in_net);
+  bool out_net_ports = hasPort(out_net);
+  return in_net_ports && out_net_ports;
+}
+
+void
+Resizer::removeBuffer(Instance *buffer)
+{
+  LibertyCell *lib_cell = network_->libertyCell(buffer);
+  LibertyPort *in_port, *out_port;
+  lib_cell->bufferPorts(in_port, out_port);
+  Pin *in_pin = db_network_->findPin(buffer, in_port);
+  Pin *out_pin = db_network_->findPin(buffer, out_port);
+  Net *in_net = db_network_->net(in_pin);
+  Net *out_net = db_network_->net(out_pin);
+  bool out_net_ports = hasPort(out_net);
+  Net *survivor, *removed;
+  if (out_net_ports) {
+    survivor = out_net;
+    removed = in_net;
+  }
+  else {
+    // default or out_net_ports
+    // Default to in_net surviving so drivers (cached in dbNetwork)
+    // do not change.
+    survivor = in_net;
+    removed = out_net;
+  }
+
+  if (!sdc_->isConstrained(in_pin)
+      && !sdc_->isConstrained(out_pin)
+      && !sdc_->isConstrained(removed)
+      && !sdc_->isConstrained(buffer)) {
+    sta_->disconnectPin(in_pin);
+    sta_->disconnectPin(out_pin);
+    sta_->deleteInstance(buffer);
+
+    NetPinIterator *pin_iter = db_network_->pinIterator(removed);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      Instance *pin_inst = db_network_->instance(pin);
+      if (pin_inst != buffer) {
+        Port *pin_port = db_network_->port(pin);
+        sta_->disconnectPin(pin);
+        sta_->connectPin(pin_inst, pin_port, survivor);
+      }
+    }
+    delete pin_iter;
+    sta_->deleteNet(removed);
+    parasitics_invalid_.erase(removed);
+  }
+}
+
+void
+Resizer::ensureLevelDrvrVertices()
+{
+  if (!level_drvr_vertices_valid_) {
+    level_drvr_vertices_.clear();
+    VertexIterator vertex_iter(graph_);
+    while (vertex_iter.hasNext()) {
+      Vertex *vertex = vertex_iter.next();
+      if (vertex->isDriver(network_))
+        level_drvr_vertices_.push_back(vertex);
+    }
+    sort(level_drvr_vertices_, VertexLevelLess(network_));
+    level_drvr_vertices_valid_ = true;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::resizePreamble()
+{
+  init();
+  makeEquivCells();
+  findBuffers();
+  findTargetLoads();
+}
+
+static float
+bufferDrive(const LibertyCell *buffer)
+{
+  LibertyPort *input, *output;
+  buffer->bufferPorts(input, output);
+  return output->driveResistance();
+}
+
+void
+Resizer::findBuffers()
+{
+  LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
+  while (lib_iter->hasNext()) {
+    LibertyLibrary *lib = lib_iter->next();
+    for (LibertyCell *buffer : *lib->buffers()) {
+      if (!dontUse(buffer)
+          && isLinkCell(buffer)) {
+        buffer_cells_.push_back(buffer);
+      }
+    }
+  }
+  delete lib_iter;
+
+  if (buffer_cells_.empty())
+    logger_->error(RSZ, 22, "no buffers found.");
+
+  sort(buffer_cells_, [] (const LibertyCell *buffer1,
+                          const LibertyCell *buffer2) {
+                        return bufferDrive(buffer1) > bufferDrive(buffer2);
+                      });
+  buffer_lowest_drive_ = buffer_cells_[0];
+  buffer_med_drive_ = buffer_cells_[buffer_cells_.size() / 2];
+  buffer_highest_drive_ = buffer_cells_[buffer_cells_.size() - 1];
+}
+
+bool
+Resizer::isLinkCell(LibertyCell *cell)
+{
+  return network_->findLibertyCell(cell->name()) == cell;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::bufferInputs()
+{
+  init();
+  inserted_buffer_count_ = 0;
+  incrementalParasiticsBegin();
+  InstancePinIterator *port_iter = network_->pinIterator(network_->topInstance());
+  while (port_iter->hasNext()) {
+    Pin *pin = port_iter->next();
+    Vertex *vertex = graph_->pinDrvrVertex(pin);
+    Net *net = network_->net(network_->term(pin));
+    if (network_->direction(pin)->isInput()
+        && !vertex->isConstant()
+        && !sta_->isClock(pin)
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && hasPins(net))
+      // repair_design will resize to target slew.
+      bufferInput(pin, buffer_lowest_drive_);
+  }
+  delete port_iter;
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 27, "Inserted {} input buffers.", inserted_buffer_count_);
+    level_drvr_vertices_valid_ = false;
+  }
+}
+   
+bool
+Resizer::hasPins(Net *net)
+{
+  NetPinIterator *pin_iter = db_network_->pinIterator(net);
+  bool has_pins = pin_iter->hasNext();
+  delete pin_iter;
+  return has_pins;
+}
+
+Instance *
+Resizer::bufferInput(const Pin *top_pin,
+                     LibertyCell *buffer_cell)
+{
+  Term *term = db_network_->term(top_pin);
+  Net *input_net = db_network_->net(term);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  string buffer_name = makeUniqueInstName("input");
+  Instance *parent = db_network_->topInstance();
+  Net *buffer_out = makeUniqueNet();
+  Instance *buffer = db_network_->makeInstance(buffer_cell,
+                                               buffer_name.c_str(),
+                                               parent);
+  if (buffer) {
+    journalMakeBuffer(buffer);
+    Point pin_loc = db_network_->location(top_pin);
+    Point buf_loc = core_exists_ ? closestPtInRect(core_, pin_loc) : pin_loc;
+    setLocation(buffer, buf_loc);
+    designAreaIncr(area(db_network_->cell(buffer_cell)));
+    inserted_buffer_count_++;
+
+    NetPinIterator *pin_iter = db_network_->pinIterator(input_net);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      // Leave input port pin connected to input_net.
+      if (pin != top_pin) {
+        sta_->disconnectPin(pin);
+        Port *pin_port = db_network_->port(pin);
+        sta_->connectPin(db_network_->instance(pin), pin_port, buffer_out);
+      }
+    }
+    delete pin_iter;
+    sta_->connectPin(buffer, input, input_net);
+    sta_->connectPin(buffer, output, buffer_out);
+
+    parasiticsInvalid(input_net);
+    parasiticsInvalid(buffer_out);
+  }
+  return buffer;
+}
+
+void
+Resizer::setLocation(Instance *inst,
+                     Point pt)
+{
+  int x = pt.getX();
+  int y = pt.getY();
+  // Stay inside the lines.
+  if (core_exists_) {
+    Point in_core = closestPtInRect(core_, x, y);
+    x = in_core.getX();
+    y = in_core.getY();
+  }
+
+  dbInst *dinst = db_network_->staToDb(inst);
+  dinst->setPlacementStatus(dbPlacementStatus::PLACED);
+  dinst->setLocation(x, y);
+}
+
+void
+Resizer::bufferOutputs()
+{
+  init();
+  inserted_buffer_count_ = 0;
+  incrementalParasiticsBegin();
+  InstancePinIterator *port_iter = network_->pinIterator(network_->topInstance());
+  while (port_iter->hasNext()) {
+    Pin *pin = port_iter->next();
+    Vertex *vertex = graph_->pinLoadVertex(pin);
+    Net *net = network_->net(network_->term(pin));
+    if (network_->direction(pin)->isOutput()
+        && net
+        // DEF does not have tristate output types so we have look at the drivers.
+        && !hasTristateDriver(net)
+        && !vertex->isConstant()
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && hasPins(net))
+      bufferOutput(pin, buffer_lowest_drive_);
+  }
+  delete port_iter;
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 28, "Inserted {} output buffers.", inserted_buffer_count_);
+    level_drvr_vertices_valid_ = false;
+  }
+}
+
+bool
+Resizer::hasTristateDriver(const Net *net)
+{
+  PinSet *drivers = network_->drivers(net);
+  if (drivers) {
+    for (Pin *pin : *drivers) {
+      if (isTristateDriver(pin))
+        return true;
+    }
+  }
+  return false;
+}
+
+bool
+Resizer::isTristateDriver(const Pin *pin)
+{
+  // Note LEF macro PINs do not have a clue about tristates.
+  LibertyPort *port = network_->libertyPort(pin);
+  return port && port->direction()->isAnyTristate();
+}
+
+void
+Resizer::bufferOutput(Pin *top_pin,
+                      LibertyCell *buffer_cell)
+{
+  NetworkEdit *network = networkEdit();
+  Term *term = network_->term(top_pin);
+  Net *output_net = network_->net(term);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  string buffer_name = makeUniqueInstName("output");
+  Instance *parent = network->topInstance();
+  Net *buffer_in = makeUniqueNet();
+  Instance *buffer = network->makeInstance(buffer_cell,
+                                           buffer_name.c_str(),
+                                           parent);
+  if (buffer) {
+    journalMakeBuffer(buffer);
+    setLocation(buffer, db_network_->location(top_pin));
+    designAreaIncr(area(db_network_->cell(buffer_cell)));
+    inserted_buffer_count_++;
+
+    NetPinIterator *pin_iter = network->pinIterator(output_net);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      if (pin != top_pin) {
+        // Leave output port pin connected to output_net.
+        sta_->disconnectPin(pin);
+        Port *pin_port = network->port(pin);
+        sta_->connectPin(network->instance(pin), pin_port, buffer_in);
+      }
+    }
+    delete pin_iter;
+    sta_->connectPin(buffer, input, buffer_in);
+    sta_->connectPin(buffer, output, output_net);
+
+    parasiticsInvalid(buffer_in);
+    parasiticsInvalid(output_net);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Repair long wires, max slew, max capacitance, max fanout violations
+// The whole enchilada.
+// max_wire_length zero for none (meters)
+void
+Resizer::repairDesign(double max_wire_length,
+                      double slew_margin,
+                      double max_cap_margin)
+{
+  int repair_count, slew_violations, cap_violations;
+  int fanout_violations, length_violations;
+  repairDesign(max_wire_length, slew_margin, max_cap_margin,
+               repair_count, slew_violations, cap_violations,
+               fanout_violations, length_violations);
+
+  if (slew_violations > 0)
+    logger_->info(RSZ, 34, "Found {} slew violations.", slew_violations);
+  if (fanout_violations > 0)
+    logger_->info(RSZ, 35, "Found {} fanout violations.", fanout_violations);
+  if (cap_violations > 0)
+    logger_->info(RSZ, 36, "Found {} capacitance violations.", cap_violations);
+  if (length_violations > 0)
+    logger_->info(RSZ, 37, "Found {} long wires.", length_violations);
+  if (inserted_buffer_count_ > 0)
+    logger_->info(RSZ, 38, "Inserted {} buffers in {} nets.",
+                  inserted_buffer_count_,
+                  repair_count);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 39, "Resized {} instances.", resize_count_);
+}
+
+void
+Resizer::repairDesign(double max_wire_length, // zero for none (meters)
+                      double slew_margin,
+                      double max_cap_margin,
+                      int &repair_count,
+                      int &slew_violations,
+                      int &cap_violations,
+                      int &fanout_violations,
+                      int &length_violations)
+{
+  repair_count = 0;
+  slew_violations = 0;
+  cap_violations = 0;
+  fanout_violations = 0;
+  length_violations = 0;
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+
+  sta_->checkSlewLimitPreamble();
+  sta_->checkCapacitanceLimitPreamble();
+  sta_->checkFanoutLimitPreamble();
+
+  incrementalParasiticsBegin();
+  int max_length = metersToDbu(max_wire_length);
+  for (int i = level_drvr_vertices_.size() - 1; i >= 0; i--) {
+    Vertex *drvr = level_drvr_vertices_[i];
+    Pin *drvr_pin = drvr->pin();
+    Net *net = network_->isTopLevelPort(drvr_pin)
+      ? network_->net(network_->term(drvr_pin))
+      : network_->net(drvr_pin);
+    if (net
+        && !sta_->isClock(drvr_pin)
+        // Exclude tie hi/low cells and supply nets.
+        && !drvr->isConstant())
+      repairNet(net, drvr_pin, drvr, slew_margin, max_cap_margin,
+                true, true, true, max_length, true,
+                repair_count, slew_violations, cap_violations,
+                fanout_violations, length_violations);
+  }
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0)
+    level_drvr_vertices_valid_ = false;
+}
+
+// repairDesign but restricted to clock network and
+// no max_fanout/max_cap checks.
+void
+Resizer::repairClkNets(double max_wire_length) // max_wire_length zero for none (meters)
+{
+  init();
+  // Need slews to resize inserted buffers.
+  sta_->findDelays();
+
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+
+  int repair_count = 0;
+  int slew_violations = 0;
+  int cap_violations = 0;
+  int fanout_violations = 0;
+  int length_violations = 0;
+  int max_length = metersToDbu(max_wire_length);
+  incrementalParasiticsBegin();
+  for (Clock *clk : sdc_->clks()) {
+    for (const Pin *clk_pin : *sta_->pins(clk)) {
+      Net *net = network_->isTopLevelPort(clk_pin)
+        ? network_->net(network_->term(clk_pin))
+        : network_->net(clk_pin);
+      if (network_->isDriver(clk_pin)) {
+        Vertex *drvr = graph_->pinDrvrVertex(clk_pin);
+        // Do not resize clock tree gates.
+        repairNet(net, clk_pin, drvr, 0.0, 0.0,
+                  false, false, false, max_length, false,
+                  repair_count, slew_violations, cap_violations,
+                  fanout_violations, length_violations);
+      }
+    }
+  }
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (length_violations > 0)
+    logger_->info(RSZ, 47, "Found {} long wires.", length_violations);
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 48, "Inserted {} buffers in {} nets.",
+                  inserted_buffer_count_,
+                  repair_count);
+    level_drvr_vertices_valid_ = false;
+  }
+}
+
+// Repair one net (for debugging)
+void
+Resizer::repairNet(Net *net,
+                   double max_wire_length, // meters
+                   double slew_margin,
+                   double max_cap_margin)
+{
+  init();
+
+  sta_->checkSlewLimitPreamble();
+  sta_->checkCapacitanceLimitPreamble();
+  sta_->checkFanoutLimitPreamble();
+
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+  resized_multi_output_insts_.clear();
+  int repair_count = 0;
+  int slew_violations = 0;
+  int cap_violations = 0;
+  int fanout_violations = 0;
+  int length_violations = 0;
+  int max_length = metersToDbu(max_wire_length);
+  PinSet *drivers = network_->drivers(net);
+  if (drivers && !drivers->empty()) {
+    PinSet::Iterator drvr_iter(drivers);
+    Pin *drvr_pin = drvr_iter.next();
+    Vertex *drvr = graph_->pinDrvrVertex(drvr_pin);
+    repairNet(net, drvr_pin, drvr, slew_margin, max_cap_margin,
+              true, true, true, max_length, true,
+              repair_count, slew_violations, cap_violations,
+              fanout_violations, length_violations);
+  }
+
+  if (slew_violations > 0)
+    logger_->info(RSZ, 51, "Found {} slew violations.", slew_violations);
+  if (fanout_violations > 0)
+    logger_->info(RSZ, 52, "Found {} fanout violations.", fanout_violations);
+  if (cap_violations > 0)
+    logger_->info(RSZ, 53, "Found {} capacitance violations.", cap_violations);
+  if (length_violations > 0)
+    logger_->info(RSZ, 54, "Found {} long wires.", length_violations);
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 55, "Inserted {} buffers in {} nets.",
+                  inserted_buffer_count_,
+                  repair_count);
+    level_drvr_vertices_valid_ = false;
+  }
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 56, "Resized {} instances.", resize_count_);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 57, "Resized {} instances.", resize_count_);
+}
+
+void
+Resizer::repairNet(Net *net,
+                   const Pin *drvr_pin,
+                   Vertex *drvr,
+                   double slew_margin,
+                   double max_cap_margin,
+                   bool check_slew,
+                   bool check_cap,
+                   bool check_fanout,
+                   int max_length, // dbu
+                   bool resize_drvr,
+                   int &repair_count,
+                   int &slew_violations,
+                   int &cap_violations,
+                   int &fanout_violations,
+                   int &length_violations)
+{
+  // Hands off special nets.
+  if (!db_network_->isSpecial(net)) {
+    SteinerTree *tree = makeSteinerTree(drvr_pin, true, max_steiner_pin_count_,
+                                        stt_builder_, db_network_, logger_);
+    if (tree) {
+      debugPrint(logger_, RSZ, "repair_net", 1, "repair net {}",
+                 sdc_network_->pathName(drvr_pin));
+      // Resize the driver to normalize slews before repairing limit violations.
+      if (resize_drvr)
+        resizeToTargetSlew(drvr_pin, true);
+      // For tristate nets all we can do is resize the driver.
+      if (!isTristateDriver(drvr_pin)) {
+        ensureWireParasitic(drvr_pin, net);
+        graph_delay_calc_->findDelays(drvr);
+
+        float max_load_slew = INF;
+        float max_cap = INF;
+        float max_fanout = INF;
+        bool repair_slew = false;
+        bool repair_cap = false;
+        bool repair_fanout = false;
+        bool repair_wire = false;
+        const Corner *corner = sta_->cmdCorner();
+        if (check_cap) {
+          float cap1, max_cap1, cap_slack1;
+          const Corner *corner1;
+          const RiseFall *tr1;
+          sta_->checkCapacitance(drvr_pin, nullptr, max_,
+                                 corner1, tr1, cap1, max_cap1, cap_slack1);
+          if (max_cap1 > 0.0 && corner1) {
+            max_cap1 *= (1.0 - max_cap_margin / 100.0);
+            max_cap = max_cap1;
+            if (cap1 > max_cap1) {
+              corner = corner1;
+              cap_violations++;
+              repair_cap = true;
+            }
+          }
+        }
+        if (check_fanout) {
+          float fanout, fanout_slack;
+          sta_->checkFanout(drvr_pin, max_,
+                            fanout, max_fanout, fanout_slack);
+          if (max_fanout > 0.0 && fanout_slack < 0.0) {
+            fanout_violations++;
+            repair_fanout = true;
+          }
+        }
+        int wire_length = findMaxSteinerDist(tree);
+        if (max_length
+            && wire_length > max_length) {
+          length_violations++;
+          repair_wire = true;
+        }
+        if (check_slew) {
+          float slew1, slew_slack1, max_slew1;
+          const Corner *corner1;
+          // Check slew at the driver.
+          checkSlew(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+          // Max slew violations at the driver pin are repaired by reducing the
+          // load capacitance. Wire resistance may shield capacitance from the
+          // driver but so this is conservative.
+          // Find max load cap that corresponds to max_slew.
+          LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+          if (corner1
+              && max_slew1 > 0.0 && drvr_port) {
+            float max_cap1 = findSlewLoadCap(drvr_port, max_slew1, corner1);
+            max_cap = min(max_cap, max_cap1);
+            corner = corner1;
+            debugPrint(logger_, RSZ, "repair_net", 2, "drvr_slew={} max_slew={} max_cap={} corner={}",
+                       delayAsString(slew1, this, 3),
+                       delayAsString(max_slew1, this, 3),
+                       units_->capacitanceUnit()->asString(max_cap1, 3),
+                       corner1->name());
+            if (slew_slack1 < 0.0)
+              repair_slew = true;
+          }
+          if (slew_slack1 < 0.0)
+            slew_violations++;
+
+          // Check slew at the loads.
+          // Note that many liberty libraries do not have max_transition attributes on
+          // input pins.
+          // Max slew violations at the load pins are repaired by reducing the
+          // wire length.
+          checkLoadSlews(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+          // Even when there are no load violations we need max_load_slew for
+          // sizing inserted buffers.
+          if (max_slew1 > 0.0) {
+            max_load_slew = max_slew1;
+            debugPrint(logger_, RSZ, "repair_net", 2, "load_slew={} max_load_slew={}",
+                       delayAsString(slew1, this, 3),
+                       delayAsString(max_load_slew, this, 3));
+            if (slew_slack1 < 0.0) {
+              // Don't double count violations on the same net.
+              if (!repair_slew)
+                slew_violations++;
+              corner = corner1;
+              repair_slew = true;
+            }
+          }
+        }
+
+        if (repair_slew
+            || repair_cap
+            || repair_fanout
+            || repair_wire) {
+          Point drvr_loc = db_network_->location(drvr->pin());
+          debugPrint(logger_, RSZ, "repair_net", 1, "driver {} ({} {}) l={}",
+                     sdc_network_->pathName(drvr_pin),
+                     units_->distanceUnit()->asString(dbuToMeters(drvr_loc.getX()), 1),
+                     units_->distanceUnit()->asString(dbuToMeters(drvr_loc.getY()), 1),
+                     units_->distanceUnit()->asString(dbuToMeters(wire_length), 1));
+          SteinerPt drvr_pt = tree->drvrPt(network_);
+          int wire_length;
+          float pin_cap, fanout;
+          PinSeq load_pins;
+          if (drvr_pt != SteinerTree::null_pt)
+            repairNet(tree, drvr_pt, SteinerTree::null_pt, net, drvr_pin,
+                      max_load_slew, max_cap, max_fanout, max_length, corner, 0,
+                      wire_length, pin_cap, fanout, load_pins);
+          repair_count++;
+
+          if (resize_drvr)
+            resizeToTargetSlew(drvr_pin, true);
+        }
+      }
+      delete tree;
+    }
+  }
+}
+
+bool
+Resizer::checkLimits(const Pin *drvr_pin,
+                     double slew_margin,
+                     double max_cap_margin,
+                     bool check_slew,
+                     bool check_cap,
+                     bool check_fanout)
+{
+  if (check_cap) {
+    float cap1, max_cap1, cap_slack1;
+    const Corner *corner1;
+    const RiseFall *tr1;
+    sta_->checkCapacitance(drvr_pin, nullptr, max_,
+                           corner1, tr1, cap1, max_cap1, cap_slack1);
+    max_cap1 *= (1.0 - max_cap_margin / 100.0);
+    if (cap1 < max_cap1)
+      return true;
+  }
+  if (check_fanout) {
+    float fanout, fanout_slack, max_fanout;
+    sta_->checkFanout(drvr_pin, max_,
+                      fanout, max_fanout, fanout_slack);
+    if (fanout_slack < 0.0)
+      return true;
+
+  }
+  if (check_slew) {
+    float slew1, slew_slack1, max_slew1;
+    const Corner *corner1;
+    checkSlew(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+    if (slew_slack1 < 0.0)
+      return true;
+    checkLoadSlews(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+    if (slew_slack1 < 0.0)
+      return true;
+  }
+  return false;
+}
+
+void
+Resizer::checkSlew(const Pin *drvr_pin,
+                   double slew_margin,
+                   // Return values.
+                   Slew &slew,
+                   float &limit,
+                   float &slack,
+                   const Corner *&corner)
+{
+  slack = INF;
+  limit = INF;
+  corner = nullptr;
+
+  const Corner *corner1;
+  const RiseFall *tr1;
+  Slew slew1;
+  float limit1, slack1;
+  sta_->checkSlew(drvr_pin, nullptr, max_, false,
+                  corner1, tr1, slew1, limit1, slack1);
+  if (corner1) {
+    limit1 *= (1.0 - slew_margin / 100.0);
+    slack1 = limit1 - slew1;
+    if (slack1 < slack) {
+      slew = slew1;
+      limit = limit1;
+      slack = slack1;
+      corner = corner1;
+    }
+  }
+}
+
+void
+Resizer::checkLoadSlews(const Pin *drvr_pin,
+                        double slew_margin,
+                        // Return values.
+                        Slew &slew,
+                        float &limit,
+                        float &slack,
+                        const Corner *&corner)
+{
+  slack = INF;
+  limit = INF;
+  PinConnectedPinIterator *pin_iter = network_->connectedPinIterator(drvr_pin);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (pin != drvr_pin) {
+      const Corner *corner1;
+      const RiseFall *tr1;
+      Slew slew1;
+      float limit1, slack1;
+      sta_->checkSlew(pin, nullptr, max_, false,
+                      corner1, tr1, slew1, limit1, slack1);
+      if (corner1) {
+        limit1 *= (1.0 - slew_margin / 100.0);
+        limit = min(limit, limit1);
+        slack1 = limit1 - slew1;
+        if (slack1 < slack) {
+          slew = slew1;
+          slack = slack1;
+          corner = corner1;
+        }
+      }
+    }
+  }
+  delete pin_iter;
+}
+
+// Find the output port load capacitance that results in slew.
+double
+Resizer::findSlewLoadCap(LibertyPort *drvr_port,
+                         double slew,
+                         const Corner *corner)
+{
+  const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+  // cap1 lower bound
+  // cap2 upper bound
+  double cap1 = 0.0;
+  double cap2 = slew / drvr_port->driveResistance() * 2;
+  double tol = .01; // 1%
+  double diff1 = gateSlewDiff(drvr_port, cap2, slew, dcalc_ap);
+  // binary search for diff = 0.
+  while (abs(cap1 - cap2) > max(cap1, cap2) * tol) {
+    if (diff1 < 0.0) {
+      cap1 = cap2;
+      cap2 *= 2;
+      diff1 = gateSlewDiff(drvr_port, cap2, slew, dcalc_ap);
+    }
+    else {
+      double cap3 = (cap1 + cap2) / 2.0;
+      double diff2 = gateSlewDiff(drvr_port, cap3, slew, dcalc_ap);
+      if (diff2 < 0.0) {
+        cap1 = cap3;
+      }
+      else {
+        cap2 = cap3;
+        diff1 = diff2;
+      }
+    }
+  }
+  return cap1;
+}
+
+// objective function
+double
+Resizer::gateSlewDiff(LibertyPort *drvr_port,
+                      double load_cap,
+                      double slew,
+                      const DcalcAnalysisPt *dcalc_ap)
+{
+  ArcDelay delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(drvr_port, load_cap, dcalc_ap, delays, slews);
+  Slew gate_slew = max(slews[RiseFall::riseIndex()], slews[RiseFall::fallIndex()]);
+  return gate_slew - slew;
+}
+
+void
+Resizer::repairNet(SteinerTree *tree,
+                   SteinerPt pt,
+                   SteinerPt prev_pt,
+                   Net *net,
+                   const Pin *drvr_pin,
+                   float max_load_slew,
+                   float max_cap,
+                   float max_fanout,
+                   int max_length, // dbu
+                   const Corner *corner,
+                   int level,
+                   // Return values.
+                   // Remaining parasiics after repeater insertion.
+                   int &wire_length, // dbu
+                   float &pin_cap,
+                   float &fanout,
+                   PinSeq &load_pins)
+{
+  Point pt_loc = tree->location(pt);
+  int pt_x = pt_loc.getX();
+  int pt_y = pt_loc.getY();
+  debugPrint(logger_, RSZ, "repair_net", 2, "{:{}s}pt ({} {})",
+             "", level,
+             units_->distanceUnit()->asString(dbuToMeters(pt_x), 1),
+             units_->distanceUnit()->asString(dbuToMeters(pt_y), 1));
+  double wire_cap = wireSignalCapacitance(corner);
+  double wire_res = wireSignalResistance(corner);
+  SteinerPt left = tree->left(pt);
+  int wire_length_left = 0;
+  float pin_cap_left = 0.0;
+  float fanout_left = 0.0;
+  PinSeq loads_left;
+  if (left != SteinerTree::null_pt)
+    repairNet(tree, left, pt, net, drvr_pin, max_load_slew, max_cap, max_fanout, max_length,
+              corner, level+1,
+              wire_length_left, pin_cap_left, fanout_left, loads_left);
+  SteinerPt right = tree->right(pt);
+  int wire_length_right = 0;
+  float pin_cap_right = 0.0;
+  float fanout_right = 0.0;
+  PinSeq loads_right;
+  if (right != SteinerTree::null_pt)
+    repairNet(tree, right, pt, net, drvr_pin, max_load_slew, max_cap, max_fanout, max_length,
+              corner, level+1,
+              wire_length_right, pin_cap_right, fanout_right, loads_right);
+  debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}left l={} pin_cap={} fanout={}, right l={} pin_cap={} fanout={}",
+             "", level,
+             units_->distanceUnit()->asString(dbuToMeters(wire_length_left), 1),
+             units_->capacitanceUnit()->asString(pin_cap_left, 3),
+             fanout_left,
+             units_->distanceUnit()->asString(dbuToMeters(wire_length_right), 1),
+             units_->capacitanceUnit()->asString(pin_cap_right, 3),
+             fanout_right);
+  // Add a buffer to left or right branch to stay under the max cap/length/fanout.
+  bool repeater_left = false;
+  bool repeater_right = false;
+  double cap_left = pin_cap_left + dbuToMeters(wire_length_left) * wire_cap;
+  double cap_right = pin_cap_right + dbuToMeters(wire_length_right) * wire_cap;
+  debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}cap_left={}, right_cap={}",
+             "", level,
+             units_->capacitanceUnit()->asString(cap_left, 3),
+             units_->capacitanceUnit()->asString(cap_right, 3));
+
+  double wire_length1 = dbuToMeters(wire_length_left + wire_length_right);
+  float load_cap = cap_left + cap_right;
+
+  LibertyCell *buffer_cell = findTargetCell(buffer_lowest_drive_, load_cap, false);
+  LibertyPort *input, *buffer_output;
+  buffer_cell->bufferPorts(input, buffer_output);
+  float r_buffer = buffer_output->driveResistance();
+  float r_drv = driveResistance(drvr_pin);
+  float r_drvr = max(r_drv, r_buffer);
+  // Elmore factor for 20-80% slew thresholds.
+  float k_threshold = 1.39;
+  Slew load_slew = (r_drvr + wire_length1 * wire_res) * load_cap * k_threshold;
+  debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}load_slew={} r_drvr={} r_buffer={}",
+             "", level,
+             delayAsString(load_slew, this, 3),
+             units_->resistanceUnit()->asString(r_drv, 3),
+             units_->resistanceUnit()->asString(r_buffer, 3));
+
+  bool slew_violation = load_slew > max_load_slew;
+  if (slew_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}slew violation", "", level);
+    if (cap_left > cap_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+
+  bool cap_violation = (cap_left + cap_right) > max_cap;
+  if (cap_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}cap violation", "", level);
+    if (cap_left > cap_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+  bool length_violation = max_length > 0
+    && (wire_length_left + wire_length_right) > max_length;
+  if (length_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}length violation", "", level);
+    if (wire_length_left > wire_length_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+  bool fanout_violation = max_fanout > 0
+    // Note that if both fanout_left==max_fanout and fanout_right==max_fanout
+    // there is no way repair the violation (adding a buffer to either branch
+    // results in max_fanout+1, which is a violation).
+    // Leave room for one buffer on the other branch by using >= to avoid
+    // this situation.
+    && (fanout_left + fanout_right) >= max_fanout;
+  if (fanout_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}fanout violation", "", level);
+    if (fanout_left > fanout_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+
+  if (repeater_left)
+    makeRepeater("left", tree, pt, buffer_cell, level,
+                 wire_length_left, pin_cap_left, fanout_left, loads_left);
+  if (repeater_right)
+    makeRepeater("right", tree, pt, buffer_cell, level,
+                 wire_length_right, pin_cap_right, fanout_right, loads_right);
+
+  // Update after left/right repeaters are inserted.
+  wire_length = wire_length_left + wire_length_right;
+  pin_cap = pin_cap_left + pin_cap_right;
+  fanout = fanout_left + fanout_right;
+
+  // Union left/right load pins.
+  for (Pin *load_pin : loads_left)
+    load_pins.push_back(load_pin);
+  for (Pin *load_pin : loads_right)
+    load_pins.push_back(load_pin);
+
+  // Steiner pt pin is the net driver if prev_pt is null.
+  if (prev_pt != SteinerTree::null_pt) {
+    const PinSeq *pt_pins = tree->pins(pt);
+    if (pt_pins) {
+      for (Pin *load_pin : *pt_pins) {
+        Point load_loc = db_network_->location(load_pin);
+        int load_dist = Point::manhattanDistance(load_loc, pt_loc);
+        debugPrint(logger_, RSZ, "repair_net", 2, "{:{}s}load {} ({} {}) dist={}",
+                   "", level,
+                   sdc_network_->pathName(load_pin),
+                   units_->distanceUnit()->asString(dbuToMeters(load_loc.getX()), 1),
+                   units_->distanceUnit()->asString(dbuToMeters(load_loc.getY()), 1),
+                   units_->distanceUnit()->asString(dbuToMeters(load_dist), 1));
+        LibertyPort *load_port = network_->libertyPort(load_pin);
+        if (load_port) {
+          pin_cap += load_port->capacitance();
+          fanout += portFanoutLoad(load_port);
+        }
+        else
+          fanout += 1;
+        load_pins.push_back(load_pin);
+      }
+    }
+
+    Point prev_loc = tree->location(prev_pt);
+    int length = Point::manhattanDistance(prev_loc, pt_loc);
+    wire_length += length;
+    // Back up from pt to prev_pt adding repeaters every max_length.
+    int prev_x = prev_loc.getX();
+    int prev_y = prev_loc.getY();
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}wl={} l={}",
+               "", level,
+               units_->distanceUnit()->asString(dbuToMeters(wire_length), 1),
+               units_->distanceUnit()->asString(dbuToMeters(length), 1));
+    wire_length1 = dbuToMeters(wire_length);
+    load_cap = pin_cap + wire_length1 * wire_cap;
+
+    buffer_cell = findTargetCell(buffer_lowest_drive_, load_cap, false);
+    buffer_cell->bufferPorts(input, buffer_output);
+    r_buffer = buffer_output->driveResistance();
+    r_drv = driveResistance(drvr_pin);
+    r_drvr = max(r_drv, r_buffer);
+    load_slew = (r_drvr + wire_length1 * wire_res) * load_cap * k_threshold;
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}load_slew={} r_drvr={} r_buffer={}",
+               "", level,
+               delayAsString(load_slew, this, 3),
+               units_->resistanceUnit()->asString(r_drv, 3),
+               units_->resistanceUnit()->asString(r_buffer, 3));
+
+    while ((max_length > 0 && wire_length > max_length)
+           || (wire_cap > 0.0
+               // Cannot fix max cap violations from pin cap by shortening wire.
+               && pin_cap < max_cap
+               && load_cap > max_cap)
+           || load_slew > max_load_slew) {
+      // Make the wire a bit shorter than necessary to allow for
+      // offset from instance origin to pin and detailed placement movement.
+      double length_margin = .05;
+      int stub_length = std::numeric_limits<int>::max();
+      if (max_length > 0 && wire_length > max_length)
+        stub_length = min(stub_length, max_length);
+      if (wire_cap > 0.0
+          && pin_cap < max_cap
+          && load_cap > max_cap)
+        stub_length = min(stub_length, metersToDbu((max_cap - pin_cap) / wire_cap));
+      if (load_slew > max_load_slew) {
+        // Using elmore delay to approximate wire
+        // load_slew = (Rdrvr + L*Rwire) * (L*Cwire + Cpin) * k_threshold
+        // Setting this to max_slew is a quadratic in L
+        // L^2*Rwire*Cwire + L*(Rdrvr*Cwire + Rwire*Cpin) + Rdrvr*Cpin - max_slew/k_threshold
+        // Solve using quadradic eqn for L.
+        float a = wire_res * wire_cap;
+        float b = r_drvr * wire_cap + wire_res * pin_cap;
+        float c = r_drvr * pin_cap - max_load_slew / k_threshold;
+        float l = (-b + sqrt(b*b - 4 * a * c)) / (2 * a);
+        stub_length = min(stub_length, metersToDbu(l));
+      }
+
+      // Distance from pt to repeater backward toward prev_pt.
+      double buf_dist = length - (wire_length - stub_length * (1.0 - length_margin));
+      double dx = prev_x - pt_x;
+      double dy = prev_y - pt_y;
+      double d = (length == 0) ? 0.0 : buf_dist / length;
+      int buf_x = pt_x + d * dx;
+      int buf_y = pt_y + d * dy;
+      makeRepeater("wire", buf_x, buf_y, buffer_lowest_drive_, level,
+                   wire_length, pin_cap, fanout, load_pins);
+      // Update for the next round.
+      length -= buf_dist;
+      wire_length = length;
+      pt_x = buf_x;
+      pt_y = buf_y;
+
+      wire_length1 = dbuToMeters(wire_length);
+      load_cap = pin_cap + wire_length1 * wire_cap;
+      load_slew = (r_drvr + wire_length1 * wire_res) * load_cap * k_threshold;
+      debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}load_slew={}",
+                 "", level,
+                 delayAsString(load_slew, this, 3));
+      debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}wl={} l={}",
+                 "", level,
+                 units_->distanceUnit()->asString(dbuToMeters(wire_length), 1),
+                 units_->distanceUnit()->asString(dbuToMeters(length), 1));
+    }
+  }
+}
+
+void
+Resizer::makeRepeater(const char *where,
+                      SteinerTree *tree,
+                      SteinerPt pt,
+                      LibertyCell *buffer_cell,
+                      int level,
+                      int &wire_length,
+                      float &pin_cap,
+                      float &fanout,
+                      PinSeq &load_pins)
+{
+  Point pt_loc = tree->location(pt);
+  makeRepeater(where, pt_loc.getX(), pt_loc.getY(), buffer_cell, level,
+               wire_length, pin_cap, fanout, load_pins);
+}
+
+void
+Resizer::makeRepeater(const char *where,
+                      int x,
+                      int y,
+                      LibertyCell *buffer_cell,
+                      int level,
+                      int &wire_length,
+                      float &pin_cap,
+                      float &fanout,
+                      PinSeq &load_pins)
+{
+  LibertyPort *buffer_input_port, *buffer_output_port;
+  buffer_cell->bufferPorts(buffer_input_port, buffer_output_port);
+
+  string buffer_name = makeUniqueInstName("repeater");
+  debugPrint(logger_, RSZ, "repair_net", 2, "{:{}s}{} {} ({} {})",
+             "", level,
+             where,
+             buffer_name.c_str(),
+             units_->distanceUnit()->asString(dbuToMeters(x), 1),
+             units_->distanceUnit()->asString(dbuToMeters(y), 1));
+
+  // Inserting a buffer is complicated by the fact that verilog netlists
+  // use the net name for input and output ports. This means the ports
+  // cannot be moved to a different net.
+
+  // This cannot depend on the net in caller because the buffer may be inserted
+  // between the driver and the loads changing the net as the repair works its
+  // way from the loads to the driver.
+
+  Net *net = nullptr, *in_net, *out_net;
+  bool have_output_port_load = false;
+  for (Pin *pin : load_pins) {
+    if (network_->isTopLevelPort(pin)) {
+      net = network_->net(network_->term(pin));
+      if (network_->direction(pin)->isAnyOutput()) {
+        have_output_port_load = true;
+        break;
+      }
+    }
+    else
+      net = network_->net(pin);
+  }
+  Instance *parent = db_network_->topInstance();
+
+  // If the net is driven by an input port,
+  // use the net as the repeater input net so the port stays connected to it.
+  if (hasInputPort(net)
+      || !have_output_port_load) {
+    in_net = net;
+    out_net = makeUniqueNet();
+    // Copy signal type to new net.
+    dbNet *out_net_db = db_network_->staToDb(out_net);
+    dbNet *in_net_db = db_network_->staToDb(in_net);
+    out_net_db->setSigType(in_net_db->getSigType());
+
+    // Move load pins to out_net.
+    for (Pin *pin : load_pins) {
+      Port *port = network_->port(pin);
+      Instance *inst = network_->instance(pin);
+      sta_->disconnectPin(pin);
+      sta_->connectPin(inst, port, out_net);
+    }
+  }
+  else {
+    // One of the loads is an output port.
+    // Use the net as the repeater output net so the port stays connected to it.
+    in_net = makeUniqueNet();
+    out_net = net;
+    // Copy signal type to new net.
+    dbNet *out_net_db = db_network_->staToDb(out_net);
+    dbNet *in_net_db = db_network_->staToDb(in_net);
+    in_net_db->setSigType(out_net_db->getSigType());
+
+    // Move non-repeater load pins to in_net.
+    PinSet load_pins1;
+    for (Pin *pin : load_pins)
+      load_pins1.insert(pin);
+
+    NetPinIterator *pin_iter = network_->pinIterator(out_net);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      if (!load_pins1.hasKey(pin)) {
+        Port *port = network_->port(pin);
+        Instance *inst = network_->instance(pin);
+        sta_->disconnectPin(pin);
+        sta_->connectPin(inst, port, in_net);
+      }
+    }
+  }
+
+  Instance *buffer = db_network_->makeInstance(buffer_cell,
+                                               buffer_name.c_str(),
+                                               parent);
+  journalMakeBuffer(buffer);
+  Point buf_loc(x, y);
+  setLocation(buffer, buf_loc);
+  designAreaIncr(area(db_network_->cell(buffer_cell)));
+  inserted_buffer_count_++;
+
+  sta_->connectPin(buffer, buffer_input_port, in_net);
+  sta_->connectPin(buffer, buffer_output_port, out_net);
+
+  parasiticsInvalid(in_net);
+  parasiticsInvalid(out_net);
+
+  // Resize repeater as we back up by levels.
+  Pin *drvr_pin = network_->findPin(buffer, buffer_output_port);
+  resizeToTargetSlew(drvr_pin, false);
+  buffer_cell = network_->libertyCell(buffer);
+  buffer_cell->bufferPorts(buffer_input_port, buffer_output_port);
+
+  Pin *buf_in_pin = network_->findPin(buffer, buffer_input_port);
+  load_pins.clear();
+  load_pins.push_back(buf_in_pin);
+  wire_length = 0;
+  pin_cap = buffer_input_port->capacitance();
+  fanout = portFanoutLoad(buffer_input_port);
+}
+
+bool
+Resizer::hasInputPort(const Net *net)
+{
+  bool has_top_level_port = false;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isTopLevelPort(pin)
+        && network_->direction(pin)->isAnyInput()) {
+      has_top_level_port = true;
+      break;
+    }
+  }
+  delete pin_iter;
+  return has_top_level_port;
+}
+
+bool
+Resizer::hasOutputPort(const Net *net)
+{
+  bool has_top_level_port = false;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isTopLevelPort(pin)
+        && network_->direction(pin)->isAnyOutput()) {
+      has_top_level_port = true;
+      break;
+    }
+  }
+  delete pin_iter;
+  return has_top_level_port;
+}
+
+bool
+Resizer::hasPort(const Net *net)
+{
+  bool has_top_level_port = false;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isTopLevelPort(pin)) {
+      has_top_level_port = true;
+      break;
+    }
+  }
+  delete pin_iter;
+  return has_top_level_port;
+}
+
+float
+Resizer::driveResistance(const Pin *drvr_pin)
+{
+  if (network_->isTopLevelPort(drvr_pin)) {
+    InputDrive *drive = sdc_->findInputDrive(network_->port(drvr_pin));
+    if (drive) {
+      float max_res = 0;
+      for (auto min_max : MinMax::range()) {
+        for (auto rf : RiseFall::range()) {
+          LibertyCell *cell;
+          LibertyPort *from_port;
+          float *from_slews;
+          LibertyPort *to_port;
+          drive->driveCell(rf, min_max, cell, from_port, from_slews, to_port);
+          if (to_port)
+            max_res = max(max_res, to_port->driveResistance());
+          else {
+            float res;
+            bool exists;
+            drive->driveResistance(rf, min_max, res, exists);
+            max_res = max(max_res, res);
+          }
+        }
+      }
+      return max_res;
+    }
+  }
+  else {
+    LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+    if (drvr_port)
+      return drvr_port->driveResistance();
+  }
+  return 0.0;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::resizeToTargetSlew()
+{
+  resize_count_ = 0;
+  resized_multi_output_insts_.clear();
+  incrementalParasiticsBegin();
+  // Resize in reverse level order.
+  for (int i = level_drvr_vertices_.size() - 1; i >= 0; i--) {
+    Vertex *drvr = level_drvr_vertices_[i];
+    Pin *drvr_pin = drvr->pin();
+    Net *net = network_->net(drvr_pin);
+    if (net
+        && !drvr->isConstant()
+        && hasFanout(drvr)
+        // Hands off the clock nets.
+        && !sta_->isClock(drvr_pin)
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)) {
+      resizeToTargetSlew(drvr_pin, true);
+      if (overMaxArea()) {
+        logger_->error(RSZ, 24, "Max utilization reached.");
+        break;
+      }
+    }
+  }
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 29, "Resized {} instances.", resize_count_);
+}
+
+bool
+Resizer::hasFanout(Vertex *drvr)
+{
+  VertexOutEdgeIterator edge_iter(drvr, graph_);
+  return edge_iter.hasNext();
+}
+
+void
+Resizer::makeEquivCells()
+{
+  LibertyLibrarySeq libs;
+  LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
+  while (lib_iter->hasNext()) {
+    LibertyLibrary *lib = lib_iter->next();
+    // massive kludge until makeEquivCells is fixed to only incldue link cells
+    LibertyCellIterator cell_iter(lib);
+    if (cell_iter.hasNext()) {
+      LibertyCell *cell = cell_iter.next();
+      if (isLinkCell(cell))
+        libs.push_back(lib);
+    }
+  }
+  delete lib_iter;
+  sta_->makeEquivCells(&libs, nullptr);
+}
+
+static float
+targetLoadDist(float load_cap,
+               float target_load)
+{
+  return abs(load_cap - target_load);
+}
+
+bool
+Resizer::resizeToTargetSlew(const Pin *drvr_pin,
+                            bool update_count)
+{
+  Instance *inst = network_->instance(drvr_pin);
+  LibertyCell *cell = network_->libertyCell(inst);
+  if (cell) {
+    bool revisiting_inst = false;
+    if (hasMultipleOutputs(inst)) {
+      revisiting_inst = resized_multi_output_insts_.hasKey(inst);
+      debugPrint(logger_, RSZ, "resize", 2, "multiple outputs{}",
+                 revisiting_inst ? " - revisit" : "");
+      resized_multi_output_insts_.insert(inst);
+    }
+    ensureWireParasitic(drvr_pin);
+    // Includes net parasitic capacitance.
+    float load_cap = graph_delay_calc_->loadCap(drvr_pin, tgt_slew_dcalc_ap_);
+    // DINESH-A: delay cells resize disabled
+    if (load_cap > 0.00 && (strncmp(cell->name(),"sky130_fd_sc_hd__clkdlybuf4s15_2",26) != 0)) {
+      LibertyCell *target_cell = findTargetCell(cell, load_cap, revisiting_inst);
+      if (target_cell != cell) {
+        //printf("Dinesh-A: Resizing : %s => %s %s Load_cap: %f \n",sdc_network_->pathName(drvr_pin),cell->name(),target_cell->name(),load_cap);
+        debugPrint(logger_, RSZ, "resize", 2, "{} {} -> {}",
+                   sdc_network_->pathName(drvr_pin),
+                   cell->name(),
+                   target_cell->name());
+        if (replaceCell(inst, target_cell, true)
+            && !revisiting_inst
+            && update_count)
+          resize_count_++;
+      }
+    }
+  }
+  return false;
+}
+
+LibertyCell *
+Resizer::findTargetCell(LibertyCell *cell,
+                        float load_cap,
+                        bool revisiting_inst)
+{
+  LibertyCell *best_cell = cell;
+  LibertyCellSeq *equiv_cells = sta_->equivCells(cell);
+  if (equiv_cells) {
+    bool is_buf_inv = cell->isBuffer() || cell->isInverter();
+    float target_load = (*target_load_map_)[cell];
+    float best_load = target_load;
+    float best_dist = targetLoadDist(load_cap, target_load);
+    float best_delay = is_buf_inv
+      ? bufferDelay(cell, load_cap, tgt_slew_dcalc_ap_)
+      : 0.0;
+    debugPrint(logger_, RSZ, "resize", 3, "{} load cap {} dist={:.2e} delay={}",
+               cell->name(),
+               units_->capacitanceUnit()->asString(load_cap),
+               best_dist,
+               delayAsString(best_delay, sta_, 3));
+    for (LibertyCell *target_cell : *equiv_cells) {
+      if (!dontUse(target_cell)
+          && isLinkCell(target_cell)) {
+        float target_load = (*target_load_map_)[target_cell];
+        float delay = is_buf_inv
+          ? bufferDelay(target_cell, load_cap, tgt_slew_dcalc_ap_)
+          : 0.0;
+        float dist = targetLoadDist(load_cap, target_load);
+        debugPrint(logger_, RSZ, "resize", 3, " {} dist={:.2e} delay={}",
+                   target_cell->name(),
+                   dist,
+                   delayAsString(delay, sta_, 3));
+        if (is_buf_inv
+            // Library may have "delay" buffers/inverters that are
+            // functionally buffers/inverters but have additional
+            // intrinsic delay. Accept worse target load matching if
+            // delay is reduced to avoid using them.
+            ? ((delay < best_delay
+                && dist < best_dist * 1.1)
+               || (dist < best_dist
+                   && delay < best_delay * 1.1))
+            : dist < best_dist
+            // If the instance has multiple outputs (generally a register Q/QN)
+            // only allow upsizing after the first pin is visited.
+            && (!revisiting_inst
+                || target_load > best_load)) {
+          best_cell = target_cell;
+          best_dist = dist;
+          best_load = target_load;
+          best_delay = delay;
+        }
+      }
+    }
+  }
+  return best_cell;
+}
+
+// Replace LEF with LEF so ports stay aligned in instance.
+bool
+Resizer::replaceCell(Instance *inst,
+                     LibertyCell *replacement,
+                     bool journal)
+{
+  const char *replacement_name = replacement->name();
+  dbMaster *replacement_master = db_->findMaster(replacement_name);
+  if (replacement_master) {
+    dbInst *dinst = db_network_->staToDb(inst);
+    dbMaster *master = dinst->getMaster();
+    designAreaIncr(-area(master));
+    Cell *replacement_cell1 = db_network_->dbToSta(replacement_master);
+    if (journal)
+      journalInstReplaceCellBefore(inst);
+    sta_->replaceCell(inst, replacement_cell1);
+    designAreaIncr(area(replacement_master));
+
+    // Invalidate estimated parasitics on all instance pins.
+    // Input nets change pin cap, outputs change location (slightly).
+    if (haveEstimatedParasitics()) {
+      InstancePinIterator *pin_iter = network_->pinIterator(inst);
+      while (pin_iter->hasNext()) {
+        const Pin *pin = pin_iter->next();
+        const Net *net = network_->net(pin);
+        if (net)
+          parasiticsInvalid(net);
+      }
+      delete pin_iter;
+    }
+    return true;
+  }
+  return false;
+}
+
+bool
+Resizer::hasMultipleOutputs(const Instance *inst)
+{
+  int output_count = 0;
+  InstancePinIterator *pin_iter = network_->pinIterator(inst);
+  while (pin_iter->hasNext()) {
+    const Pin *pin = pin_iter->next();
+    if (network_->direction(pin)->isAnyOutput()
+        && network_->net(pin)) {
+      output_count++;
+      if (output_count > 1)
+        return true;
+    }
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::resizeSlackPreamble()
+{
+  resizePreamble();
+  // Save max_wire_length for multiple repairDesign calls.
+  max_wire_length_ = findMaxWireLength();
+  net_slack_map_.clear();
+}
+
+// Run repair design to find the slacks but save/restore all changes to the netlist.
+void
+Resizer::findResizeSlacks()
+{
+  journalBegin();
+  estimateWireParasitics();
+  int repair_count, slew_violations, cap_violations;
+  int fanout_violations, length_violations;
+  repairDesign(max_wire_length_, 0.0, 0.0,
+               repair_count, slew_violations, cap_violations,
+               fanout_violations, length_violations);
+  findResizeSlacks1();
+  journalRestore();
+}
+  
+void
+Resizer::findResizeSlacks1()
+{
+  // Use driver pin slacks rather than Sta::netSlack to save visiting
+  // the net pins and min'ing the slack.
+  NetSeq nets;
+  for (int i = level_drvr_vertices_.size() - 1; i >= 0; i--) {
+    Vertex *drvr = level_drvr_vertices_[i];
+    Pin *drvr_pin = drvr->pin();
+    Net *net = network_->isTopLevelPort(drvr_pin)
+      ? network_->net(network_->term(drvr_pin))
+      : network_->net(drvr_pin);
+    if (net
+        && !drvr->isConstant()
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && !sta_->isClock(drvr_pin)) {
+      net_slack_map_[net] = sta_->vertexSlack(drvr, max_);
+      nets.push_back(net);
+    }
+  }
+
+  // Find the nets with the worst slack.
+  double worst_percent = .1;
+  //  sort(nets.begin(), nets.end(). [&](const Net *net1,
+  sort(nets, [this](const Net *net1,
+                 const Net *net2)
+             { return resizeNetSlack(net1) < resizeNetSlack(net2); });
+  worst_slack_nets_.clear();
+  for (int i = 0; i < nets.size() * worst_percent; i++)
+    worst_slack_nets_.push_back(nets[i]);
+}
+
+NetSeq &
+Resizer::resizeWorstSlackNets()
+{
+  return worst_slack_nets_;
+}
+
+vector<dbNet*>
+Resizer::resizeWorstSlackDbNets()
+{
+  vector<dbNet*> nets;
+  for (Net* net : worst_slack_nets_)
+    nets.push_back(db_network_->staToDb(net));
+  return nets;
+}
+
+Slack
+Resizer::resizeNetSlack(const Net *net)
+{
+  return net_slack_map_[net];
+}
+
+Slack
+Resizer::resizeNetSlack(const dbNet *db_net)
+{
+  const Net *net = db_network_->dbToSta(db_net);
+  return net_slack_map_[net];
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::area(Cell *cell)
+{
+  return area(db_network_->staToDb(cell));
+}
+
+double
+Resizer::area(dbMaster *master)
+{
+  if (!master->isCoreAutoPlaceable()) {
+    return 0;
+  }
+  return dbuToMeters(master->getWidth()) * dbuToMeters(master->getHeight());
+}
+
+double
+Resizer::dbuToMeters(int dist) const
+{
+  int dbu = db_->getTech()->getDbUnitsPerMicron();
+  return dist / (dbu * 1e+6);
+}
+
+int
+Resizer::metersToDbu(double dist) const
+{
+  int dbu = db_->getTech()->getDbUnitsPerMicron();
+  return dist * dbu * 1e+6;
+}
+
+void
+Resizer::setMaxUtilization(double max_utilization)
+{
+  max_area_ = coreArea() * max_utilization;
+}
+
+bool
+Resizer::overMaxArea()
+{
+  return max_area_
+    && fuzzyGreaterEqual(design_area_, max_area_);
+}
+
+void
+Resizer::setDontUse(LibertyCellSeq *dont_use)
+{
+  if (dont_use) {
+    for (LibertyCell *cell : *dont_use)
+      dont_use_.insert(cell);
+  }
+}
+
+bool
+Resizer::dontUse(LibertyCell *cell)
+{
+  return cell->dontUse()
+    || dont_use_.hasKey(cell);
+}
+
+////////////////////////////////////////////////////////////////
+
+// Find a target slew for the libraries and then
+// a target load for each cell that gives the target slew.
+void
+Resizer::findTargetLoads()
+{
+  // Find target slew across all buffers in the libraries.
+  findBufferTargetSlews();
+  if (target_load_map_ == nullptr)
+    target_load_map_ = new CellTargetLoadMap;
+  target_load_map_->clear();
+
+  // Find target loads at the tgt_slew_corner.
+  int lib_ap_index = tgt_slew_corner_->libertyIndex(max_);
+  LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
+  while (lib_iter->hasNext()) {
+    LibertyLibrary *lib = lib_iter->next();
+    LibertyCellIterator cell_iter(lib);
+    while (cell_iter.hasNext()) {
+      LibertyCell *cell = cell_iter.next();
+      if (isLinkCell(cell)) {
+        LibertyCell *corner_cell = cell->cornerCell(lib_ap_index);
+        float tgt_load;
+        bool exists;
+        target_load_map_->findKey(corner_cell, tgt_load, exists);
+        if (!exists) {
+          tgt_load = findTargetLoad(corner_cell);
+          (*target_load_map_)[corner_cell] = tgt_load;
+        }
+        // Map link cell to corner cell target load.
+        if (cell != corner_cell)
+          (*target_load_map_)[cell] = tgt_load;
+      }
+    }
+  }
+  delete lib_iter;
+}
+
+float
+Resizer::targetLoadCap(LibertyCell *cell)
+{
+  float load_cap = 0.0;
+  bool exists;
+  target_load_map_->findKey(cell, load_cap, exists);
+  if (!exists)
+    logger_->error(RSZ, 68, "missing target load cap.");
+  return load_cap;
+}
+
+float
+Resizer::findTargetLoad(LibertyCell *cell)
+{
+  LibertyCellTimingArcSetIterator arc_set_iter(cell);
+  float target_load_sum = 0.0;
+  int arc_count = 0;
+  while (arc_set_iter.hasNext()) {
+    TimingArcSet *arc_set = arc_set_iter.next();
+    TimingRole *role = arc_set->role();
+    if (!role->isTimingCheck()
+        && role != TimingRole::tristateDisable()
+        && role != TimingRole::tristateEnable()) {
+      TimingArcSetArcIterator arc_iter(arc_set);
+      while (arc_iter.hasNext()) {
+        TimingArc *arc = arc_iter.next();
+        int in_rf_index = arc->fromTrans()->asRiseFall()->index();
+        int out_rf_index = arc->toTrans()->asRiseFall()->index();
+        float arc_target_load = findTargetLoad(cell, arc, 
+                                               tgt_slews_[in_rf_index],
+                                               tgt_slews_[out_rf_index]);
+        debugPrint(logger_, RSZ, "target_load", 3, "{} {} -> {} {} target_load = {:.2e}",
+                   cell->name(),
+                   arc->from()->name(),
+                   arc->to()->name(),
+                   arc->toTrans()->asString(),
+                   arc_target_load);
+        target_load_sum += arc_target_load;
+        arc_count++;
+      }
+    }
+  }
+  float target_load = arc_count ? target_load_sum / arc_count : 0.0;
+  debugPrint(logger_, RSZ, "target_load", 2, "{} target_load = {:.2e}",
+             cell->name(),
+             target_load);
+  return target_load;
+}
+
+// Find the load capacitance that will cause the output slew
+// to be equal to out_slew.
+float
+Resizer::findTargetLoad(LibertyCell *cell,
+                        TimingArc *arc,
+                        Slew in_slew,
+                        Slew out_slew)
+{
+  GateTimingModel *model = dynamic_cast<GateTimingModel*>(arc->model());
+  if (model) {
+    // load_cap1 lower bound
+    // load_cap2 upper bound
+    double load_cap1 = 0.0;
+    double load_cap2 = 1.0e-12;  // 1pF
+    double tol = .01; // 1%
+    double diff1 = gateSlewDiff(cell, arc, model, in_slew, load_cap1, out_slew);
+    if (diff1 > 0.0)
+      // Zero load cap out_slew is higher than the target.
+      return 0.0;
+    double diff2 = gateSlewDiff(cell, arc, model, in_slew, load_cap2, out_slew);
+    // binary search for diff = 0.
+    while (abs(load_cap1 - load_cap2) > max(load_cap1, load_cap2) * tol) {
+      if (diff2 < 0.0) {
+        load_cap1 = load_cap2;
+        diff1 = diff2;
+        load_cap2 *= 2;
+        diff2 = gateSlewDiff(cell, arc, model, in_slew, load_cap2, out_slew);
+      }
+      else {
+        double load_cap3 = (load_cap1 + load_cap2) / 2.0;
+        double diff3 = gateSlewDiff(cell, arc, model, in_slew, load_cap3, out_slew);
+        if (diff3 < 0.0) {
+          load_cap1 = load_cap3;
+          diff1 = diff3;
+        }
+        else {
+          load_cap2 = load_cap3;
+          diff2 = diff3;
+        }
+      }
+    }
+    return load_cap1;
+  }
+  return 0.0;
+}
+
+// objective function
+Slew
+Resizer::gateSlewDiff(LibertyCell *cell,
+                      TimingArc *arc,
+                      GateTimingModel *model,
+                      Slew in_slew,
+                      float load_cap,
+                      Slew out_slew)
+
+{
+  const Pvt *pvt = tgt_slew_dcalc_ap_->operatingConditions();
+  ArcDelay arc_delay;
+  Slew arc_slew;
+  model->gateDelay(cell, pvt, in_slew, load_cap, 0.0, false,
+                   arc_delay, arc_slew);
+  return arc_slew - out_slew;
+}
+
+////////////////////////////////////////////////////////////////
+
+Slew
+Resizer::targetSlew(const RiseFall *rf)
+{
+  return tgt_slews_[rf->index()];
+}
+
+// Find target slew across all buffers in the libraries.
+void
+Resizer::findBufferTargetSlews()
+{
+  tgt_slews_ = {0.0};
+  tgt_slew_corner_ = nullptr;
+  
+  for (Corner *corner : *sta_->corners()) {
+    int lib_ap_index = corner->libertyIndex(max_);
+    const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+    const Pvt *pvt = dcalc_ap->operatingConditions();
+    // Average slews across buffers at corner.
+    Slew slews[RiseFall::index_count]{0.0};
+    int counts[RiseFall::index_count]{0};
+    for (LibertyCell *buffer : buffer_cells_) {
+      LibertyCell *corner_buffer = buffer->cornerCell(lib_ap_index);
+      findBufferTargetSlews(corner_buffer, pvt, slews, counts);
+    }
+    Slew slew_rise = slews[RiseFall::riseIndex()] / counts[RiseFall::riseIndex()];
+    Slew slew_fall = slews[RiseFall::fallIndex()] / counts[RiseFall::fallIndex()];
+    // Use the target slews from the slowest corner,
+    // and resize using that corner.
+    if (slew_rise > tgt_slews_[RiseFall::riseIndex()]) {
+      tgt_slews_[RiseFall::riseIndex()] = slew_rise;
+      tgt_slews_[RiseFall::fallIndex()] = slew_fall;
+      tgt_slew_corner_ = corner;
+      tgt_slew_dcalc_ap_ = corner->findDcalcAnalysisPt(max_);
+    }
+  }
+
+  debugPrint(logger_, RSZ, "target_load", 1, "target slew corner {} = {}/{}",
+             tgt_slew_corner_->name(),
+             delayAsString(tgt_slews_[RiseFall::riseIndex()], sta_, 3),
+             delayAsString(tgt_slews_[RiseFall::fallIndex()], sta_, 3));
+}
+
+void
+Resizer::findBufferTargetSlews(LibertyCell *buffer,
+                               const Pvt *pvt,
+                               // Return values.
+                               Slew slews[],
+                               int counts[])
+{
+  LibertyPort *input, *output;
+  buffer->bufferPorts(input, output);
+  TimingArcSetSeq *arc_sets = buffer->timingArcSets(input, output);
+  if (arc_sets) {
+    for (TimingArcSet *arc_set : *arc_sets) {
+      TimingArcSetArcIterator arc_iter(arc_set);
+      while (arc_iter.hasNext()) {
+        TimingArc *arc = arc_iter.next();
+        GateTimingModel *model = dynamic_cast<GateTimingModel*>(arc->model());
+        RiseFall *in_rf = arc->fromTrans()->asRiseFall();
+        RiseFall *out_rf = arc->toTrans()->asRiseFall();
+        float in_cap = input->capacitance(in_rf, max_);
+        float load_cap = in_cap * tgt_slew_load_cap_factor;
+        ArcDelay arc_delay;
+        Slew arc_slew;
+        model->gateDelay(buffer, pvt, 0.0, load_cap, 0.0, false,
+                         arc_delay, arc_slew);
+        model->gateDelay(buffer, pvt, arc_slew, load_cap, 0.0, false,
+                         arc_delay, arc_slew);
+        slews[out_rf->index()] += arc_slew;
+        counts[out_rf->index()]++;
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Repair tie hi/low net driver fanout by duplicating the
+// tie hi/low instances for every pin connected to tie hi/low instances.
+void
+Resizer::repairTieFanout(LibertyPort *tie_port,
+                         double separation, // meters
+                         bool verbose)
+{
+  ensureBlock();
+  ensureDesignArea();
+  Instance *top_inst = network_->topInstance();
+  LibertyCell *tie_cell = tie_port->libertyCell();
+  InstanceSeq insts;
+  findCellInstances(tie_cell, insts);
+  int tie_count = 0;
+  int separation_dbu = metersToDbu(separation);
+  for (Instance *inst : insts) {
+    Pin *drvr_pin = network_->findPin(inst, tie_port);
+    if (drvr_pin) {
+      const char *inst_name = network_->name(inst);
+      Net *net = network_->net(drvr_pin);
+      if (net) {
+        NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+        while (pin_iter->hasNext()) {
+          Pin *load = pin_iter->next();
+          if (load != drvr_pin) {
+            // Make tie inst.
+            Point tie_loc = tieLocation(load, separation_dbu);
+            Instance *load_inst = network_->instance(load);
+            string tie_name = makeUniqueInstName(inst_name, true);
+            Instance *tie = sta_->makeInstance(tie_name.c_str(),
+                                               tie_cell, top_inst);
+            setLocation(tie, tie_loc);
+
+            // Make tie output net.
+            Net *load_net = makeUniqueNet();
+
+            // Connect tie inst output.
+            sta_->connectPin(tie, tie_port, load_net);
+
+            // Connect load to tie output net.
+            sta_->disconnectPin(load);
+            Port *load_port = network_->port(load);
+            sta_->connectPin(load_inst, load_port, load_net);
+
+            designAreaIncr(area(db_network_->cell(tie_cell)));
+            tie_count++;
+          }
+        }
+        delete pin_iter;
+
+        // Delete inst output net.
+        Pin *tie_pin = network_->findPin(inst, tie_port);
+        Net *tie_net = network_->net(tie_pin);
+        sta_->deleteNet(tie_net);
+        parasitics_invalid_.erase(tie_net);
+        // Delete the tie instance.
+        sta_->deleteInstance(inst);
+      }
+    }
+  }
+
+  if (tie_count > 0) {
+    logger_->info(RSZ, 42, "Inserted {} tie {} instances.",
+                  tie_count,
+                  tie_cell->name());
+    level_drvr_vertices_valid_ = false;
+  }
+}
+
+void
+Resizer::findCellInstances(LibertyCell *cell,
+                           // Return value.
+                           InstanceSeq &insts)
+{
+  LeafInstanceIterator *inst_iter = network_->leafInstanceIterator();
+  while (inst_iter->hasNext()) {
+    Instance *inst = inst_iter->next();
+    if (network_->libertyCell(inst) == cell)
+      insts.push_back(inst);
+  }
+  delete inst_iter;
+}
+
+// Place the tie instance on the side of the load pin.
+Point
+Resizer::tieLocation(Pin *load,
+                     int separation)
+{
+  Point load_loc = db_network_->location(load);
+  int load_x = load_loc.getX();
+  int load_y = load_loc.getY();
+  int tie_x = load_x;
+  int tie_y = load_y;
+  if (!network_->isTopLevelPort(load)) {
+    dbInst *db_inst = db_network_->staToDb(network_->instance(load));
+    dbBox *bbox = db_inst->getBBox();
+    int left_dist = abs(load_x - bbox->xMin());
+    int right_dist = abs(load_x - bbox->xMax());
+    int bot_dist = abs(load_y - bbox->yMin());
+    int top_dist = abs(load_y - bbox->yMax());
+    if (left_dist < right_dist
+        && left_dist < bot_dist
+        && left_dist < top_dist)
+      // left
+      tie_x -= separation;
+    if (right_dist < left_dist
+        && right_dist < bot_dist
+        && right_dist < top_dist)
+      // right
+      tie_x += separation;
+    if (bot_dist < left_dist
+        && bot_dist < right_dist
+        && bot_dist < top_dist)
+      // bot
+      tie_y -= separation;
+    if (top_dist < left_dist
+        && top_dist < right_dist
+        && top_dist < bot_dist)
+      // top
+      tie_y += separation;
+  }
+  return Point(tie_x, tie_y);
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::repairSetup(float slack_margin)
+{
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+  Slack worst_slack;
+  Vertex *worst_vertex;
+  sta_->worstSlack(max_, worst_slack, worst_vertex);
+  debugPrint(logger_, RSZ, "repair_setup", 1, "worst_slack = {}",
+             delayAsString(worst_slack, sta_, 3));
+  Slack prev_worst_slack = -INF;
+  int pass = 1;
+  int decreasing_slack_passes = 0;
+  incrementalParasiticsBegin();
+  while (fuzzyLess(worst_slack, slack_margin)) {
+    PathRef worst_path = sta_->vertexWorstSlackPath(worst_vertex, max_);
+    bool changed = repairSetup(worst_path, worst_slack);
+    updateParasitics();
+    sta_->findRequireds();
+    sta_->worstSlack(max_, worst_slack, worst_vertex);
+    bool decreasing_slack = fuzzyLessEqual(worst_slack, prev_worst_slack);
+    debugPrint(logger_, RSZ, "repair_setup", 1, "pass {} worst_slack = {} {}",
+               pass,
+               delayAsString(worst_slack, sta_, 3),
+               decreasing_slack ? "v" : "^");
+    if (decreasing_slack) {
+      // Allow slack to increase to get out of local minima.
+      // Do not update prev_worst_slack so it saves the high water mark.
+      decreasing_slack_passes++;
+      if (!changed
+          || decreasing_slack_passes > repair_setup_decreasing_slack_passes_allowed_) {
+        // Undo changes that reduced slack.
+        journalRestore();
+        debugPrint(logger_, RSZ, "repair_setup", 1,
+                   "decreasing slack for {} passes. Restoring best slack {}",
+                   decreasing_slack_passes,
+                   delayAsString(prev_worst_slack, sta_, 3));
+        break;
+      }
+    }
+    else {
+      prev_worst_slack = worst_slack;
+      decreasing_slack_passes = 0;
+      // Progress, start journal so we can back up to here.
+      journalBegin();
+    }
+    if (overMaxArea())
+      break;
+    pass++;
+  }
+  // Leave the parasitics up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0)
+    logger_->info(RSZ, 40, "Inserted {} buffers.", inserted_buffer_count_);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 41, "Resized {} instances.", resize_count_);
+  if (fuzzyLess(worst_slack, slack_margin))
+    logger_->warn(RSZ, 62, "Unable to repair all setup violations.");
+  if (overMaxArea())
+    logger_->error(RSZ, 25, "max utilization reached.");
+}
+
+// For testing.
+void
+Resizer::repairSetup(Pin *end_pin)
+{
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+  Vertex *vertex = graph_->pinLoadVertex(end_pin);
+  Slack slack = sta_->vertexSlack(vertex, max_);
+  PathRef path = sta_->vertexWorstSlackPath(vertex, max_);
+  incrementalParasiticsBegin();
+  repairSetup(path, slack);
+  // Leave the parasitices up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0)
+    logger_->info(RSZ, 30, "Inserted {} buffers.", inserted_buffer_count_);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 31, "Resized {} instances.", resize_count_);
+}
+
+bool
+Resizer::repairSetup(PathRef &path,
+                     Slack path_slack)
+{
+  PathExpanded expanded(&path, sta_);
+  bool changed = false;
+  if (expanded.size() > 1) {
+    int path_length = expanded.size();
+    vector<pair<int, Delay>> load_delays;
+    int start_index = expanded.startIndex();
+    const DcalcAnalysisPt *dcalc_ap = path.dcalcAnalysisPt(sta_);
+    int lib_ap = dcalc_ap->libertyIndex();
+    // Find load delay for each gate in the path.
+    for (int i = start_index; i < path_length; i++) {
+      PathRef *path = expanded.path(i);
+      Vertex *path_vertex = path->vertex(sta_);
+      const Pin *path_pin = path->pin(sta_);
+      if (network_->isDriver(path_pin)
+          && !network_->isTopLevelPort(path_pin)) {
+        TimingArc *prev_arc = expanded.prevArc(i);
+        TimingArc *corner_arc = prev_arc->cornerArc(lib_ap);
+        Edge *prev_edge = path->prevEdge(prev_arc, sta_);
+        Delay load_delay = graph_->arcDelay(prev_edge, prev_arc, dcalc_ap->index())
+          // Remove intrinsic delay to find load dependent delay.
+          - corner_arc->intrinsicDelay();
+        load_delays.push_back(pair(i, load_delay));
+        debugPrint(logger_, RSZ, "repair_setup", 3, "{} load_delay = {}",
+                   path_vertex->name(network_),
+                   delayAsString(load_delay, sta_, 3));
+      }
+    }
+
+    sort(load_delays.begin(), load_delays.end(),
+         [](pair<int, Delay> pair1,
+            pair<int, Delay> pair2) {
+           return pair1.second > pair2.second;
+         });
+    // Attack gates with largest load delays first.
+    for (auto index_delay : load_delays) {
+      int drvr_index = index_delay.first;
+      PathRef *drvr_path = expanded.path(drvr_index);
+      Vertex *drvr_vertex = drvr_path->vertex(sta_);
+      Pin *drvr_pin = drvr_vertex->pin();
+      PathRef *load_path = expanded.path(drvr_index + 1);
+      Vertex *load_vertex = load_path->vertex(sta_);
+      Pin *load_pin = load_vertex->pin();
+      int fanout = this->fanout(drvr_vertex);
+      debugPrint(logger_, RSZ, "repair_setup", 2, "{} fanout = {}",
+                 network_->pathName(drvr_pin),
+                 fanout);
+      // For tristate nets all we can do is resize the driver.
+      bool tristate_drvr = isTristateDriver(drvr_pin);
+      if (fanout > 1
+          // Rebuffer blows up on large fanout nets.
+          && fanout < rebuffer_max_fanout_
+          && !tristate_drvr) {
+        int count_before = inserted_buffer_count_;
+        rebuffer(drvr_pin);
+        int insert_count = inserted_buffer_count_ - count_before;
+        if (insert_count > 0) {
+          debugPrint(logger_, RSZ, "repair_setup", 2, "rebuffer {} inserted {}",
+                     network_->pathName(drvr_pin),
+                     insert_count);
+          changed = true;
+          break;
+        }
+      }
+      // Don't split loads on low fanout nets.
+      if (fanout > split_load_min_fanout_
+          && !tristate_drvr) {
+        // Divide and conquer.
+        debugPrint(logger_, RSZ, "repair_setup", 2, "split loads {} -> {}",
+                   network_->pathName(drvr_pin),
+                   network_->pathName(load_pin));
+        splitLoads(drvr_path, path_slack);
+        changed = true;
+        break;
+      }
+      LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+      float load_cap = graph_delay_calc_->loadCap(drvr_pin, dcalc_ap);
+      int in_index = drvr_index - 1;
+      PathRef *in_path = expanded.path(in_index);
+      Pin *in_pin = in_path->pin(sta_);
+      LibertyPort *in_port = network_->libertyPort(in_pin);
+
+      float prev_drive;
+      if (drvr_index >= 2) {
+        int prev_drvr_index = drvr_index - 2;
+        PathRef *prev_drvr_path = expanded.path(prev_drvr_index);
+        Pin *prev_drvr_pin = prev_drvr_path->pin(sta_);
+        prev_drive = 0.0;
+        LibertyPort *prev_drvr_port = network_->libertyPort(prev_drvr_pin);
+        if (prev_drvr_port) {
+          prev_drive = prev_drvr_port->driveResistance();
+        }
+      }
+      else
+        prev_drive = 0.0;
+      LibertyCell *upsize = upsizeCell(in_port, drvr_port, load_cap,
+                                       prev_drive, dcalc_ap);
+      // DINESH-A: delay cells resize disabled
+      if (upsize && (strncmp(drvr_port->libertyCell()->name(),"sky130_fd_sc_hd__clkdlybuf4s15_2",26) != 0)) {
+        Instance *drvr = network_->instance(drvr_pin);
+	//printf("Dinesh-A: Upsizing the cells: %s %s %s\n",network_->pathName(drvr_pin),drvr_port->libertyCell()->name(),upsize->name());
+        debugPrint(logger_, RSZ, "repair_setup", 2, "resize {} {} -> {}",
+                   network_->pathName(drvr_pin),
+                   drvr_port->libertyCell()->name(),
+                   upsize->name());
+        if (replaceCell(drvr, upsize, true)) {
+          resize_count_++;
+          changed = true;
+          break;
+        }
+      }
+    }
+  }
+  return changed;
+}
+
+void
+Resizer::splitLoads(PathRef *drvr_path,
+                    Slack drvr_slack)
+{
+  Vertex *drvr_vertex = drvr_path->vertex(sta_);
+  const RiseFall *rf = drvr_path->transition(sta_);
+  // Sort fanouts of the drvr on the critical path by slack margin
+  // wrt the critical path slack.
+  vector<pair<Vertex*, Slack>> fanout_slacks;
+  VertexOutEdgeIterator edge_iter(drvr_vertex, graph_);
+  while (edge_iter.hasNext()) {
+    Edge *edge = edge_iter.next();
+    Vertex *fanout_vertex = edge->to(graph_);
+    Slack fanout_slack = sta_->vertexSlack(fanout_vertex, rf, max_);
+    Slack slack_margin = fanout_slack - drvr_slack;
+    debugPrint(logger_, RSZ, "repair_setup", 3, " fanin {} slack_margin = {}",
+               network_->pathName(fanout_vertex->pin()),
+               delayAsString(slack_margin, sta_, 3));
+    fanout_slacks.push_back(pair<Vertex*, Slack>(fanout_vertex, slack_margin));
+  }
+
+  sort(fanout_slacks.begin(), fanout_slacks.end(),
+       [](pair<Vertex*, Slack> pair1,
+          pair<Vertex*, Slack> pair2) {
+         return pair1.second > pair2.second;
+       });
+
+  Pin *drvr_pin = drvr_vertex->pin();
+  Net *net = network_->net(drvr_pin);
+
+  string buffer_name = makeUniqueInstName("split");
+  Instance *parent = db_network_->topInstance();
+  LibertyCell *buffer_cell = buffer_lowest_drive_;
+  Instance *buffer = db_network_->makeInstance(buffer_cell,
+                                               buffer_name.c_str(),
+                                               parent);
+  journalMakeBuffer(buffer);
+  inserted_buffer_count_++;
+  designAreaIncr(area(db_network_->cell(buffer_cell)));
+
+  Net *out_net = makeUniqueNet();
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  Point drvr_loc = db_network_->location(drvr_pin);
+  setLocation(buffer, drvr_loc);
+
+  // Split the loads with extra slack to an inserted buffer.
+  // before
+  // drvr_pin -> net -> load_pins
+  // after
+  // drvr_pin -> net -> load_pins with low slack
+  //                 -> buffer_in -> net -> rest of loads
+  sta_->connectPin(buffer, input, net);
+  parasiticsInvalid(net);
+  sta_->connectPin(buffer, output, out_net);
+  int split_index = fanout_slacks.size() / 2;
+  for (int i = 0; i < split_index; i++) {
+    pair<Vertex*, Slack> fanout_slack = fanout_slacks[i];
+    Vertex *load_vertex = fanout_slack.first;
+    Pin *load_pin = load_vertex->pin();
+    // Leave ports connected to original net so verilog port names are preserved.
+    if (!network_->isTopLevelPort(load_pin)) {
+      LibertyPort *load_port = network_->libertyPort(load_pin);
+      Instance *load = network_->instance(load_pin);
+
+      sta_->disconnectPin(load_pin);
+      sta_->connectPin(load, load_port, out_net);
+    }
+  }
+  Pin *buffer_out_pin = network_->findPin(buffer, output);
+  resizeToTargetSlew(buffer_out_pin, false);
+}
+
+LibertyCell *
+Resizer::upsizeCell(LibertyPort *in_port,
+                    LibertyPort *drvr_port,
+                    float load_cap,
+                    float prev_drive,
+                    const DcalcAnalysisPt *dcalc_ap)
+{
+  int lib_ap = dcalc_ap->libertyIndex();
+  LibertyCell *cell = drvr_port->libertyCell();
+  LibertyCellSeq *equiv_cells = sta_->equivCells(cell);
+  if (equiv_cells) {
+    const char *in_port_name = in_port->name();
+    const char *drvr_port_name = drvr_port->name();
+    sort(equiv_cells,
+         [=] (const LibertyCell *cell1,
+              const LibertyCell *cell2) {
+           LibertyPort *port1=cell1->findLibertyPort(drvr_port_name)->cornerPort(lib_ap);
+           LibertyPort *port2=cell2->findLibertyPort(drvr_port_name)->cornerPort(lib_ap);
+           return port1->driveResistance() > port2->driveResistance();
+         });
+    float drive = drvr_port->cornerPort(lib_ap)->driveResistance();
+    float delay = gateDelay(drvr_port, load_cap, tgt_slew_dcalc_ap_)
+      + prev_drive * in_port->cornerPort(lib_ap)->capacitance();
+    for (LibertyCell *equiv : *equiv_cells) {
+      LibertyCell *equiv_corner = equiv->cornerCell(lib_ap);
+      LibertyPort *equiv_drvr = equiv_corner->findLibertyPort(drvr_port_name);
+      LibertyPort *equiv_input = equiv_corner->findLibertyPort(in_port_name);
+      float equiv_drive = equiv_drvr->driveResistance();
+      // Include delay of previous driver into equiv gate.
+      float equiv_delay = gateDelay(equiv_drvr, load_cap, dcalc_ap)
+        + prev_drive * equiv_input->capacitance();
+      if (!dontUse(equiv)
+          && equiv_drive < drive
+          && equiv_delay < delay)
+        return equiv;
+    }
+  }
+  return nullptr;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::repairHold(float slack_margin,
+                    bool allow_setup_violations,
+                    // Max buffer count as percent of design instance count.
+                    float max_buffer_percent)
+{
+  init();
+  LibertyCell *buffer_cell = findHoldBuffer();
+  sta_->findRequireds();
+  VertexSet *ends = sta_->search()->endpoints();
+  int max_buffer_count = max_buffer_percent * network_->instanceCount();
+  incrementalParasiticsBegin();
+  repairHold(ends, buffer_cell, slack_margin,
+             allow_setup_violations, max_buffer_count);
+
+  // Leave the parasitices up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+}
+
+// For testing/debug.
+void
+Resizer::repairHold(Pin *end_pin,
+                    LibertyCell *buffer_cell,
+                    float slack_margin,
+                    bool allow_setup_violations,
+                    float max_buffer_percent)
+{
+  Vertex *end = graph_->pinLoadVertex(end_pin);
+  VertexSet ends;
+  ends.insert(end);
+
+  init();
+  sta_->findRequireds();
+  int max_buffer_count = max_buffer_percent * network_->instanceCount();
+  incrementalParasiticsBegin();
+  repairHold(&ends, buffer_cell, slack_margin, allow_setup_violations,
+             max_buffer_count);
+  // Leave the parasitices up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+}
+
+// Find the buffer with the most delay in the fastest corner.
+LibertyCell *
+Resizer::findHoldBuffer()
+{
+  LibertyCell *max_buffer = nullptr;
+  float max_delay = 0.0;
+  for (LibertyCell *buffer : buffer_cells_) {
+    float buffer_min_delay = bufferHoldDelay(buffer);
+    if (max_buffer == nullptr
+        || buffer_min_delay > max_delay) {
+      max_buffer = buffer;
+      max_delay = buffer_min_delay;
+    }
+  }
+  return max_buffer;
+}
+
+float
+Resizer::bufferHoldDelay(LibertyCell *buffer)
+{
+  Delay delays[RiseFall::index_count];
+  bufferHoldDelays(buffer, delays);
+  return min(delays[RiseFall::riseIndex()],
+             delays[RiseFall::fallIndex()]);
+}
+
+// Min self delay across corners; buffer -> buffer
+void
+Resizer::bufferHoldDelays(LibertyCell *buffer,
+                          // Return values.
+                          Delay delays[RiseFall::index_count])
+{
+  LibertyPort *input, *output;
+  buffer->bufferPorts(input, output);
+
+  for (int rf_index : RiseFall::rangeIndex())
+    delays[rf_index] = MinMax::min()->initValue();
+  for (Corner *corner : *sta_->corners()) {
+    LibertyPort *corner_port = input->cornerPort(corner->libertyIndex(max_));
+    const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+    float load_cap = corner_port->capacitance();
+    ArcDelay gate_delays[RiseFall::index_count];
+    Slew slews[RiseFall::index_count];
+    gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+    for (int rf_index : RiseFall::rangeIndex())
+      delays[rf_index] = min(delays[rf_index], gate_delays[rf_index]);
+  }
+}
+
+void
+Resizer::repairHold(VertexSet *ends,
+                    LibertyCell *buffer_cell,
+                    float slack_margin,
+                    bool allow_setup_violations,
+                    int max_buffer_count)
+{
+  // Find endpoints with hold violation.
+  VertexSet hold_failures;
+  Slack worst_slack;
+  findHoldViolations(ends, slack_margin, worst_slack, hold_failures);
+  if (!hold_failures.empty()) {
+    logger_->info(RSZ, 46, "Found {} endpoints with hold violations.",
+                  hold_failures.size());
+    inserted_buffer_count_ = 0;
+    int repair_count = 1;
+    int pass = 1;
+    while (!hold_failures.empty()
+           // Make sure we are making progress.
+           && repair_count > 0
+           && !overMaxArea()
+           && inserted_buffer_count_ <= max_buffer_count) {
+      repair_count = repairHoldPass(hold_failures, buffer_cell, slack_margin,
+                                    allow_setup_violations, max_buffer_count);
+      debugPrint(logger_, RSZ, "repair_hold", 1,
+                 "pass {} worst slack {} failures {} inserted {}",
+                 pass,
+                 delayAsString(worst_slack, sta_, 3),
+                 hold_failures .size(),
+                 repair_count);
+      sta_->findRequireds();
+      findHoldViolations(ends, slack_margin, worst_slack, hold_failures);
+      pass++;
+    }
+    if (slack_margin == 0.0 && fuzzyLess(worst_slack, 0.0))
+      logger_->warn(RSZ, 66, "Unable to repair all hold violations.");
+    else if (fuzzyLess(worst_slack, slack_margin))
+      logger_->warn(RSZ, 64, "Unable to repair all hold checks within margin.");
+
+    if (inserted_buffer_count_ > 0) {
+      logger_->info(RSZ, 32, "Inserted {} hold buffers.", inserted_buffer_count_);
+      level_drvr_vertices_valid_ = false;
+    }
+    if (inserted_buffer_count_ > max_buffer_count)
+      logger_->error(RSZ, 60, "Max buffer count reached.");
+    if (overMaxArea())
+      logger_->error(RSZ, 50, "Max utilization reached.");
+  }
+  else
+    logger_->info(RSZ, 33, "No hold violations found.");
+}
+
+void
+Resizer::findHoldViolations(VertexSet *ends,
+                            float slack_margin,
+                            // Return values.
+                            Slack &worst_slack,
+                            VertexSet &hold_violations)
+{
+  worst_slack = INF;
+  hold_violations.clear();
+  debugPrint(logger_, RSZ, "repair_hold", 3, "Hold violations");
+  for (Vertex *end : *ends) {
+    Slack slack = sta_->vertexSlack(end, MinMax::min());
+    if (!sta_->isClock(end->pin())
+        && fuzzyLess(slack, slack_margin)) {
+      debugPrint(logger_, RSZ, "repair_hold", 3, " {}",
+                 end->name(sdc_network_));
+      if (slack < worst_slack)
+        worst_slack = slack;
+      hold_violations.insert(end);
+    }
+  }
+}
+
+int
+Resizer::repairHoldPass(VertexSet &hold_failures,
+                        LibertyCell *buffer_cell,
+                        float slack_margin,
+                        bool allow_setup_violations,
+                        int max_buffer_count)
+{
+  VertexSet fanins = findHoldFanins(hold_failures);
+  VertexSeq sorted_fanins = sortHoldFanins(fanins);
+  
+  int repair_count = 0;
+  int max_repair_count = max(static_cast<int>(hold_failures.size() * .2), 10);
+  for(int i = 0; i < sorted_fanins.size() && repair_count < max_repair_count ; i++) {
+    Vertex *vertex = sorted_fanins[i];
+    Pin *drvr_pin = vertex->pin();
+    Net *net = network_->isTopLevelPort(drvr_pin)
+      ? network_->net(network_->term(drvr_pin))
+      : network_->net(drvr_pin);
+    updateParasitics();
+    Slack drvr_slacks[RiseFall::index_count][MinMax::index_count];
+    sta_->vertexSlacks(vertex, drvr_slacks);
+    int min_index = MinMax::minIndex();
+    int max_index = MinMax::maxIndex();
+    const RiseFall *drvr_rf = (drvr_slacks[RiseFall::riseIndex()][min_index] <
+                               drvr_slacks[RiseFall::fallIndex()][min_index])
+      ? RiseFall::rise()
+      : RiseFall::fall();
+    Slack drvr_hold_slack = drvr_slacks[drvr_rf->index()][min_index] - slack_margin;
+    Slack drvr_setup_slack = drvr_slacks[drvr_rf->index()][max_index];
+    if (!vertex->isConstant()
+        && fuzzyLess(drvr_hold_slack, 0.0)
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && !isTristateDriver(drvr_pin)
+        // Have to have enough setup slack to add delay to repair the hold violation.
+        && (allow_setup_violations
+            || fuzzyLess(drvr_hold_slack, drvr_setup_slack))) {
+      debugPrint(logger_, RSZ, "repair_hold", 2, "driver {}",
+                 vertex->name(sdc_network_));
+      // Only add delay to loads with hold violations.
+      PinSeq load_pins;
+      float load_cap = 0.0;
+      bool loads_have_out_port = false;
+      VertexOutEdgeIterator edge_iter(vertex, graph_);
+      while (edge_iter.hasNext()) {
+        Edge *edge = edge_iter.next();
+        Vertex *fanout = edge->to(graph_);
+        Slack fanout_slack = sta_->vertexSlack(fanout, MinMax::min());
+        if (fanout_slack < slack_margin) {
+          Pin *fanout_pin = fanout->pin();
+          load_pins.push_back(fanout_pin);
+          if (network_->direction(fanout_pin)->isAnyOutput()
+              && network_->isTopLevelPort(fanout_pin))
+            loads_have_out_port = true;
+          else {
+            LibertyPort *fanout_port = network_->libertyPort(fanout_pin);
+            if (fanout_port)
+              load_cap += fanout_port->capacitance();
+          }
+        }
+      }
+      if (!load_pins.empty()) {
+        // multi-corner support MIA
+        const DcalcAnalysisPt *dcalc_ap = sta_->cmdCorner()->findDcalcAnalysisPt(max_);
+        Delay buffer_delay1 = bufferDelay(buffer_cell, drvr_rf, load_cap, dcalc_ap);
+        // Need enough slack to at least insert the last buffer with loads.
+        if (allow_setup_violations
+            || (buffer_delay1 < drvr_slacks[RiseFall::riseIndex()][max_index]
+                && buffer_delay1 < drvr_slacks[RiseFall::fallIndex()][max_index])) {
+          Delay buffer_delay = bufferHoldDelay(buffer_cell);
+          Delay max_insert = min(drvr_slacks[RiseFall::riseIndex()][max_index],
+                                 drvr_slacks[RiseFall::fallIndex()][max_index]);
+          int max_insert_count = delayInf(max_insert)
+            ? 1
+            : (max_insert - buffer_delay1) / buffer_delay + 1;
+          int hold_buffer_count = (-drvr_hold_slack > buffer_delay1)
+            ? std::ceil((-drvr_hold_slack-buffer_delay1)/buffer_delay)+1
+            : 1;
+          int buffer_count = allow_setup_violations
+            ? hold_buffer_count
+            : min(max_insert_count, hold_buffer_count);
+          debugPrint(logger_, RSZ, "repair_hold", 2,
+                     " {} hold={} inserted {} for {}/{} loads",
+                     vertex->name(sdc_network_),
+                     delayAsString(drvr_hold_slack, this, 3),
+                     buffer_count,
+                     load_pins.size(),
+                     fanout(vertex));
+          makeHoldDelay(vertex, buffer_count, load_pins,
+                        loads_have_out_port, buffer_cell);
+          repair_count += buffer_count;
+          if (logger_->debugCheck(RSZ, "repair_hold", 4)) {
+            // Check that no setup violations are introduced.
+            updateParasitics();
+            Slack drvr_setup_slack1 = sta_->vertexSlack(vertex, max_);
+            if (drvr_setup_slack1 < 0
+                && drvr_setup_slack1 < drvr_setup_slack)
+              printf("%s %s -> %s\n", vertex->name(network_),
+                     delayAsString(drvr_setup_slack, sta_, 3),
+                     delayAsString(drvr_setup_slack1, sta_, 3));
+          }
+          if (inserted_buffer_count_ > max_buffer_count
+              || overMaxArea())
+            return repair_count;
+        }
+      }
+    }
+  }
+  return repair_count;
+}
+
+VertexSet
+Resizer::findHoldFanins(VertexSet &ends)
+{
+  SearchPredNonReg2 pred(sta_);
+  BfsBkwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *vertex : ends)
+    iter.enqueueAdjacentVertices(vertex);
+
+  VertexSet fanins;
+  while (iter.hasNext()) {
+    Vertex *fanin = iter.next();
+    if (!sta_->isClock(fanin->pin())) {
+      if (fanin->isDriver(network_))
+        fanins.insert(fanin);
+      iter.enqueueAdjacentVertices(fanin);
+    }
+  }
+  return fanins;
+}
+
+VertexSeq
+Resizer::sortHoldFanins(VertexSet &fanins)
+{
+  VertexSeq sorted_fanins;
+  for(Vertex *vertex : fanins)
+    sorted_fanins.push_back(vertex);
+
+  sort(sorted_fanins, [&](Vertex *v1, Vertex *v2)
+                      { float s1 = sta_->vertexSlack(v1, MinMax::min());
+                        float s2 = sta_->vertexSlack(v2, MinMax::min());
+                        if (fuzzyEqual(s1, s2)) {
+                          float gap1 = slackGap(v1);
+                          float gap2 = slackGap(v2);
+                          // Break ties based on the hold/setup gap.
+                          if (fuzzyEqual(gap1, gap2))
+                            return v1->level() > v2->level();
+                          else
+                            return gap1 > gap2;
+                        }
+                        else
+                          return s1 < s2;});
+  if (logger_->debugCheck(RSZ, "repair_hold", 4)) {
+    printf("Sorted fanins");
+    printf("     hold_slack  slack_gap  level");
+    for(Vertex *vertex : sorted_fanins)
+      printf("%s %s %s %d",
+             vertex->name(network_),
+             delayAsString(sta_->vertexSlack(vertex, MinMax::min()), sta_, 3),
+             delayAsString(slackGap(vertex), sta_, 3),
+             vertex->level());
+  }
+  return sorted_fanins;
+}
+
+void
+Resizer::makeHoldDelay(Vertex *drvr,
+                       int buffer_count,
+                       PinSeq &load_pins,
+                       bool loads_have_out_port,
+                       LibertyCell *buffer_cell)
+{
+  Pin *drvr_pin = drvr->pin();
+  Instance *parent = db_network_->topInstance();
+  Net *drvr_net = network_->isTopLevelPort(drvr_pin)
+    ? db_network_->net(db_network_->term(drvr_pin))
+    : db_network_->net(drvr_pin);
+  Net *in_net, *out_net;
+  if (loads_have_out_port) {
+    // Verilog uses nets as ports, so the net connected to an output port has
+    // to be preserved.
+    // Move the driver pin over to gensym'd net.
+    in_net = makeUniqueNet();
+    Port *drvr_port = network_->port(drvr_pin);
+    Instance *drvr_inst = network_->instance(drvr_pin);
+    sta_->disconnectPin(drvr_pin);
+    sta_->connectPin(drvr_inst, drvr_port, in_net);
+    out_net = drvr_net;
+  }
+  else {
+    in_net = drvr_net;
+    out_net = makeUniqueNet();
+  }
+
+  parasiticsInvalid(in_net);
+  // Spread buffers between driver and load center.
+  Point drvr_loc = db_network_->location(drvr_pin);
+  Point load_center = findCenter(load_pins);
+  int dx = (load_center.x() - drvr_loc.x()) / (buffer_count + 1);
+  int dy = (load_center.y() - drvr_loc.y()) / (buffer_count + 1);
+
+  Net *buf_in_net = in_net;
+  Instance *buffer = nullptr;
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  // drvr_pin->in_net->hold_buffer1->net2->hold_buffer2->out_net...->load_pins
+  for (int i = 0; i < buffer_count; i++) {
+    Net *buf_out_net = (i == buffer_count - 1) ? out_net : makeUniqueNet();
+    // drvr_pin->drvr_net->hold_buffer->net2->load_pins
+    string buffer_name = makeUniqueInstName("hold");
+    buffer = db_network_->makeInstance(buffer_cell, buffer_name.c_str(),
+                                       parent);
+    journalMakeBuffer(buffer);
+    inserted_buffer_count_++;
+    designAreaIncr(area(db_network_->cell(buffer_cell)));
+
+    sta_->connectPin(buffer, input, buf_in_net);
+    sta_->connectPin(buffer, output, buf_out_net);
+    Point buffer_loc(drvr_loc.x() + dx * i,
+                     drvr_loc.y() + dy * i);
+    setLocation(buffer, buffer_loc);
+    buf_in_net = buf_out_net;
+    parasiticsInvalid(buf_out_net);
+  }
+
+  for (Pin *load_pin : load_pins) {
+    Net *load_net = network_->isTopLevelPort(load_pin)
+      ? network_->net(network_->term(load_pin))
+      : network_->net(load_pin);
+    if (load_net != out_net) {
+      Instance *load = db_network_->instance(load_pin);
+      Port *load_port = db_network_->port(load_pin);
+      sta_->disconnectPin(load_pin);
+      sta_->connectPin(load, load_port, out_net);
+    }
+  }
+  Pin *buffer_out_pin = network_->findPin(buffer, output);
+  resizeToTargetSlew(buffer_out_pin, false);
+}
+
+Point
+Resizer::findCenter(PinSeq &pins)
+{
+  long sum_x = 0;
+  long sum_y = 0;
+  for (Pin *pin : pins) {
+    Point loc = db_network_->location(pin);
+    sum_x += loc.x();
+    sum_y += loc.y();
+  }
+  return Point(sum_x / pins.size(), sum_y / pins.size());
+}
+
+// Gap between min setup and hold slacks.
+// This says how much head room there is for adding delay to fix a
+// hold violation before violating a setup check.
+Slack
+Resizer::slackGap(Slacks &slacks)
+{
+  return min(slacks[RiseFall::riseIndex()][MinMax::maxIndex()]
+             - slacks[RiseFall::riseIndex()][MinMax::minIndex()],
+             slacks[RiseFall::fallIndex()][MinMax::maxIndex()]
+             - slacks[RiseFall::fallIndex()][MinMax::minIndex()]);
+}
+
+Slack
+Resizer::slackGap(Vertex *vertex)
+{
+  Slacks slacks;
+  sta_->vertexSlacks(vertex, slacks);
+  return slackGap(slacks);
+}
+
+int
+Resizer::fanout(Vertex *vertex)
+{
+  int fanout = 0;
+  VertexOutEdgeIterator edge_iter(vertex, graph_);
+  while (edge_iter.hasNext()) {
+    edge_iter.next();
+    fanout++;
+  }
+  return fanout;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::reportLongWires(int count,
+                         int digits)
+{
+  graph_ = sta_->ensureGraph();
+  sta_->ensureClkNetwork();
+  VertexSeq drvrs;
+  findLongWires(drvrs);
+  report_->reportLine("Driver    length delay");
+  const Corner *corner = sta_->cmdCorner();
+  double wire_res = wireSignalResistance(corner);
+  double wire_cap = wireSignalCapacitance(corner);
+  int i = 0;
+  for (Vertex *drvr : drvrs) {
+    Pin *drvr_pin = drvr->pin();
+    double wire_length = dbuToMeters(maxLoadManhattenDistance(drvr));
+    double steiner_length = dbuToMeters(findMaxSteinerDist(drvr));
+    double delay = (wire_length * wire_res) * (wire_length * wire_cap) * 0.5;
+    report_->reportLine("%s manhtn %s steiner %s %s",
+                        sdc_network_->pathName(drvr_pin),
+                        units_->distanceUnit()->asString(wire_length, 1),
+                        units_->distanceUnit()->asString(steiner_length, 1),
+                        delayAsString(delay, sta_, digits));
+    if (i == count)
+      break;
+    i++;
+  }
+}
+
+typedef std::pair<Vertex*, int> DrvrDist;
+
+void
+Resizer::findLongWires(VertexSeq &drvrs)
+{
+  Vector<DrvrDist> drvr_dists;
+  VertexIterator vertex_iter(graph_);
+  while (vertex_iter.hasNext()) {
+    Vertex *vertex = vertex_iter.next();
+    if (vertex->isDriver(network_)) {
+      Pin *pin = vertex->pin();
+      // Hands off the clock nets.
+      if (!sta_->isClock(pin)
+          && !vertex->isConstant()
+          && !vertex->isDisabledConstraint())
+        drvr_dists.push_back(DrvrDist(vertex, maxLoadManhattenDistance(vertex)));
+    }
+  }
+  sort(drvr_dists, [](const DrvrDist &drvr_dist1,
+                          const DrvrDist &drvr_dist2) {
+                    return drvr_dist1.second > drvr_dist2.second;
+                  });
+  drvrs.reserve(drvr_dists.size());
+  for (DrvrDist &drvr_dist : drvr_dists)
+    drvrs.push_back(drvr_dist.first);
+}
+
+void
+Resizer::findLongWiresSteiner(VertexSeq &drvrs)
+{
+  Vector<DrvrDist> drvr_dists;
+  VertexIterator vertex_iter(graph_);
+  while (vertex_iter.hasNext()) {
+    Vertex *vertex = vertex_iter.next();
+    if (vertex->isDriver(network_)) {
+      Pin *pin = vertex->pin();
+      // Hands off the clock nets.
+      if (!sta_->isClock(pin)
+          && !vertex->isConstant())
+        drvr_dists.push_back(DrvrDist(vertex, findMaxSteinerDist(vertex)));
+    }
+  }
+  sort(drvr_dists, [](const DrvrDist &drvr_dist1,
+                          const DrvrDist &drvr_dist2) {
+                     return drvr_dist1.second > drvr_dist2.second;
+                   });
+  drvrs.reserve(drvr_dists.size());
+  for (DrvrDist &drvr_dist : drvr_dists)
+    drvrs.push_back(drvr_dist.first);
+}
+
+// Find the maximum distance along steiner tree branches from
+// the driver to loads (in dbu).
+int
+Resizer::findMaxSteinerDist(Vertex *drvr)
+{
+  Pin *drvr_pin = drvr->pin();
+  SteinerTree *tree = makeSteinerTree(drvr_pin, true, max_steiner_pin_count_,
+                                      stt_builder_, db_network_, logger_);
+  if (tree) {
+    int dist = findMaxSteinerDist(tree);
+    delete tree;
+    return dist;
+  }
+  return 0;
+}
+
+int
+Resizer::findMaxSteinerDist(SteinerTree *tree)
+{
+  SteinerPt drvr_pt = tree->drvrPt(network_);
+  if (drvr_pt == SteinerTree::null_pt)
+    return 0;
+  else
+    return findMaxSteinerDist(tree, drvr_pt, 0);
+}
+
+// DFS of steiner tree.
+int
+Resizer::findMaxSteinerDist(SteinerTree *tree,
+                            SteinerPt pt,
+                            int dist_from_drvr)
+{
+  const PinSeq *pins = tree->pins(pt);
+  if (pins) {
+    for (const Pin *pin : *pins) {
+      if (db_network_->isLoad(pin))
+        return dist_from_drvr;
+    }
+  }
+  Point loc = tree->location(pt);
+  SteinerPt left = tree->left(pt);
+  int left_max = 0;
+  if (left != SteinerTree::null_pt) {
+    int left_dist = Point::manhattanDistance(loc, tree->location(left));
+    left_max = findMaxSteinerDist(tree, left, dist_from_drvr + left_dist);
+  }
+  SteinerPt right = tree->right(pt);
+  int right_max = 0;
+  if (right != SteinerTree::null_pt) {
+    int right_dist = Point::manhattanDistance(loc, tree->location(right));
+    right_max = findMaxSteinerDist(tree, right, dist_from_drvr + right_dist);
+  }
+  return max(left_max, right_max);
+}
+
+double
+Resizer::maxLoadManhattenDistance(const Net *net)
+{
+  NetPinIterator *pin_iter = network_->pinIterator(net);
+  int max_dist = 0;
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isDriver(pin)) {
+      Vertex *drvr = graph_->pinDrvrVertex(pin);
+      if (drvr) {
+        int dist = maxLoadManhattenDistance(drvr);
+        max_dist = max(max_dist, dist);
+      }
+    }
+  }
+  delete pin_iter;
+  return dbuToMeters(max_dist);
+}
+
+int
+Resizer::maxLoadManhattenDistance(Vertex *drvr)
+{
+  int max_dist = 0;
+  Point drvr_loc = db_network_->location(drvr->pin());
+  VertexOutEdgeIterator edge_iter(drvr, graph_);
+  while (edge_iter.hasNext()) {
+    Edge *edge = edge_iter.next();
+    Vertex *load = edge->to(graph_);
+    Point load_loc = db_network_->location(load->pin());
+    int dist = Point::manhattanDistance(drvr_loc, load_loc);
+    max_dist = max(max_dist, dist);
+  }
+  return max_dist;
+}
+
+////////////////////////////////////////////////////////////////
+
+NetSeq *
+Resizer::findFloatingNets()
+{
+  NetSeq *floating_nets = new NetSeq;
+  NetIterator *net_iter = network_->netIterator(network_->topInstance());
+  while (net_iter->hasNext()) {
+    Net *net = net_iter->next();
+    PinSeq loads;
+    PinSeq drvrs;
+    PinSet visited_drvrs;
+    FindNetDrvrLoads visitor(nullptr, visited_drvrs, loads, drvrs, network_);
+    network_->visitConnectedPins(net, visitor);
+    if (drvrs.size() == 0 && loads.size() > 0)
+      floating_nets->push_back(net);
+  }
+  delete net_iter;
+  sort(floating_nets, sta::NetPathNameLess(network_));
+  return floating_nets;
+}
+
+////////////////////////////////////////////////////////////////
+
+string
+Resizer::makeUniqueNetName()
+{
+  string node_name;
+  Instance *top_inst = network_->topInstance();
+  do 
+    stringPrint(node_name, "net%d", unique_net_index_++);
+  while (network_->findNet(top_inst, node_name.c_str()));
+  return node_name;
+}
+
+Net *
+Resizer::makeUniqueNet()
+{
+  string net_name = makeUniqueNetName();
+  Instance *parent = db_network_->topInstance();
+  return db_network_->makeNet(net_name.c_str(), parent);
+}
+
+string
+Resizer::makeUniqueInstName(const char *base_name)
+{
+  return makeUniqueInstName(base_name, false);
+}
+
+string
+Resizer::makeUniqueInstName(const char *base_name,
+                            bool underscore)
+{
+  string inst_name;
+  do 
+    stringPrint(inst_name, underscore ? "%s_%d" : "%s%d",
+                base_name, unique_inst_index_++);
+  while (network_->findInstance(inst_name.c_str()));
+  return inst_name;
+}
+
+float
+Resizer::portFanoutLoad(LibertyPort *port)
+{
+  float fanout_load;
+  bool exists;
+  port->fanoutLoad(fanout_load, exists);
+  if (!exists) {
+    LibertyLibrary *lib = port->libertyLibrary();
+    lib->defaultFanoutLoad(fanout_load, exists);
+  }
+  if (exists)
+    return fanout_load;
+  else
+    return 0.0;
+}
+
+float
+Resizer::bufferDelay(LibertyCell *buffer_cell,
+                     const RiseFall *rf,
+                     float load_cap,
+                     const DcalcAnalysisPt *dcalc_ap)
+{
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return gate_delays[rf->index()];
+}
+
+float
+Resizer::bufferDelay(LibertyCell *buffer_cell,
+                     float load_cap,
+                     const DcalcAnalysisPt *dcalc_ap)
+{
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return max(gate_delays[RiseFall::riseIndex()],
+             gate_delays[RiseFall::fallIndex()]);
+}
+
+// Self delay; buffer -> buffer
+float
+Resizer::bufferSelfDelay(LibertyCell *buffer_cell)
+{
+  const DcalcAnalysisPt *dcalc_ap = sta_->cmdCorner()->findDcalcAnalysisPt(max_);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  float load_cap = input->capacitance();
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return max(gate_delays[RiseFall::riseIndex()],
+             gate_delays[RiseFall::fallIndex()]);
+}
+
+float
+Resizer::bufferSelfDelay(LibertyCell *buffer_cell,
+                         const RiseFall *rf)
+{
+  const DcalcAnalysisPt *dcalc_ap = sta_->cmdCorner()->findDcalcAnalysisPt(max_);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  float load_cap = input->capacitance();
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return gate_delays[rf->index()];
+}
+
+// Rise/fall delays across all timing arcs into drvr_port.
+// Uses target slew for input slew.
+void
+Resizer::gateDelays(LibertyPort *drvr_port,
+                    float load_cap,
+                    const DcalcAnalysisPt *dcalc_ap,
+                    // Return values.
+                    ArcDelay delays[RiseFall::index_count],
+                    Slew slews[RiseFall::index_count])
+{
+  for (int rf_index : RiseFall::rangeIndex()) {
+    delays[rf_index] = -INF;
+    slews[rf_index] = -INF;
+  }
+  const Pvt *pvt = dcalc_ap->operatingConditions();
+  LibertyCell *cell = drvr_port->libertyCell();
+  LibertyCellTimingArcSetIterator set_iter(cell);
+  while (set_iter.hasNext()) {
+    TimingArcSet *arc_set = set_iter.next();
+    if (arc_set->to() == drvr_port
+        && !arc_set->role()->isTimingCheck()) {
+      TimingArcSetArcIterator arc_iter(arc_set);
+      while (arc_iter.hasNext()) {
+        TimingArc *arc = arc_iter.next();
+        RiseFall *in_rf = arc->fromTrans()->asRiseFall();
+        int out_rf_index = arc->toTrans()->asRiseFall()->index();
+        float in_slew = tgt_slews_[in_rf->index()];
+        ArcDelay gate_delay;
+        Slew drvr_slew;
+        arc_delay_calc_->gateDelay(cell, arc, in_slew, load_cap,
+                                   nullptr, 0.0, pvt, dcalc_ap,
+                                   gate_delay,
+                                   drvr_slew);
+        delays[out_rf_index] = max(delays[out_rf_index], gate_delay);
+        slews[out_rf_index] = max(slews[out_rf_index], drvr_slew);
+      }
+    }
+  }
+}
+
+ArcDelay
+Resizer::gateDelay(LibertyPort *drvr_port,
+                   const RiseFall *rf,
+                   float load_cap,
+                   const DcalcAnalysisPt *dcalc_ap)
+{
+  ArcDelay delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(drvr_port, load_cap, dcalc_ap, delays, slews);
+  return delays[rf->index()];
+}
+
+ArcDelay
+Resizer::gateDelay(LibertyPort *drvr_port,
+                   float load_cap,
+                   const DcalcAnalysisPt *dcalc_ap)
+{
+  ArcDelay delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(drvr_port, load_cap, dcalc_ap, delays, slews);
+  return max(delays[RiseFall::riseIndex()], delays[RiseFall::fallIndex()]);
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::findMaxWireLength()
+{
+  double max_length = INF;
+  for (const Corner *corner : *sta_->corners()) {
+    if (wireSignalResistance(corner) > 0.0) {
+      for (LibertyCell *buffer_cell : buffer_cells_) {
+        double buffer_length = findMaxWireLength(buffer_cell, corner);
+        max_length = min(max_length, buffer_length);
+      }
+    }
+  }
+  return max_length;
+}
+
+// Find the max wire length before it is faster to split the wire
+// in half with a buffer (in meters).
+double
+Resizer::findMaxWireLength(LibertyCell *buffer_cell,
+                           const Corner *corner)
+{
+  ensureBlock();
+  LibertyPort *load_port, *drvr_port;
+  buffer_cell->bufferPorts(load_port, drvr_port);
+  return findMaxWireLength(drvr_port, corner);
+}
+
+double
+Resizer::findMaxWireLength(LibertyPort *drvr_port,
+                           const Corner *corner)
+{
+  LibertyCell *cell = drvr_port->libertyCell();
+  double drvr_r = drvr_port->driveResistance();
+  // wire_length1 lower bound
+  // wire_length2 upper bound
+  double wire_length1 = 0.0;
+  // Initial guess with wire resistance same as driver resistance.
+  double wire_length2 = drvr_r / wireSignalResistance(corner);
+  double tol = .01; // 1%
+  double diff1 = splitWireDelayDiff(wire_length2, cell);
+  // binary search for diff = 0.
+  while (abs(wire_length1 - wire_length2) > max(wire_length1, wire_length2) * tol) {
+    if (diff1 < 0.0) {
+      wire_length1 = wire_length2;
+      wire_length2 *= 2;
+      diff1 = splitWireDelayDiff(wire_length2, cell);
+    }
+    else {
+      double wire_length3 = (wire_length1 + wire_length2) / 2.0;
+      double diff2 = splitWireDelayDiff(wire_length3, cell);
+      if (diff2 < 0.0) {
+        wire_length1 = wire_length3;
+      }
+      else {
+        wire_length2 = wire_length3;
+        diff1 = diff2;
+      }
+    }
+  }
+  return wire_length1;
+}
+
+// objective function
+double
+Resizer::splitWireDelayDiff(double wire_length,
+                            LibertyCell *buffer_cell)
+{
+  Delay delay1, delay2;
+  Slew slew1, slew2;
+  bufferWireDelay(buffer_cell, wire_length, delay1, slew1);
+  bufferWireDelay(buffer_cell, wire_length / 2, delay2, slew2);
+  return delay1 - delay2 * 2;
+}
+
+void
+Resizer::bufferWireDelay(LibertyCell *buffer_cell,
+                         double wire_length, // meters
+                         // Return values.
+                         Delay &delay,
+                         Slew &slew)
+{
+  LibertyPort *load_port, *drvr_port;
+  buffer_cell->bufferPorts(load_port, drvr_port);
+  return cellWireDelay(drvr_port, load_port, wire_length, delay, slew);
+}
+
+// Cell delay plus wire delay.
+// Use target slew for input slew.
+// drvr_port and load_port do not have to be the same liberty cell.
+void
+Resizer::cellWireDelay(LibertyPort *drvr_port,
+                       LibertyPort *load_port,
+                       double wire_length, // meters
+                       // Return values.
+                       Delay &delay,
+                       Slew &slew)
+{
+  // Make a (hierarchical) block to use as a scratchpad.
+  dbBlock *block = dbBlock::create(block_, "wire_delay", '/');
+  dbSta *sta = makeBlockSta(openroad_, block);
+  Parasitics *parasitics = sta->parasitics();
+  Network *network = sta->network();
+  ArcDelayCalc *arc_delay_calc = sta->arcDelayCalc();
+  Corners *corners = sta->corners();
+  corners->copy(sta_->corners());
+
+  Instance *top_inst = network->topInstance();
+  // Tmp net for parasitics to live on.
+  Net *net = sta->makeNet("wire", top_inst);
+  LibertyCell *drvr_cell = drvr_port->libertyCell();
+  LibertyCell *load_cell = load_port->libertyCell();
+  Instance *drvr = sta->makeInstance("drvr", drvr_cell, top_inst);
+  Instance *load = sta->makeInstance("load", load_cell, top_inst);
+  sta->connectPin(drvr, drvr_port, net);
+  sta->connectPin(load, load_port, net);
+  Pin *drvr_pin = network->findPin(drvr, drvr_port);
+  Pin *load_pin = network->findPin(load, load_port);
+
+  // Max rise/fall delays.
+  delay = -INF;
+  slew = -INF;
+
+  for (Corner *corner : *corners) {
+    const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+    const Pvt *pvt = dcalc_ap->operatingConditions();
+
+    makeWireParasitic(net, drvr_pin, load_pin, wire_length, corner, parasitics);
+    // Let delay calc reduce parasitic network as it sees fit.
+    Parasitic *drvr_parasitic = arc_delay_calc->findParasitic(drvr_pin,
+                                                              RiseFall::rise(),
+                                                              dcalc_ap);
+    LibertyCellTimingArcSetIterator set_iter(drvr_cell);
+    while (set_iter.hasNext()) {
+      TimingArcSet *arc_set = set_iter.next();
+      if (arc_set->to() == drvr_port) {
+        TimingArcSetArcIterator arc_iter(arc_set);
+        while (arc_iter.hasNext()) {
+          TimingArc *arc = arc_iter.next();
+          RiseFall *in_rf = arc->fromTrans()->asRiseFall();
+          double in_slew = tgt_slews_[in_rf->index()];
+          ArcDelay gate_delay;
+          Slew drvr_slew;
+          arc_delay_calc->gateDelay(drvr_cell, arc, in_slew, 0.0,
+                                    drvr_parasitic, 0.0, pvt, dcalc_ap,
+                                    gate_delay,
+                                    drvr_slew);
+          ArcDelay wire_delay;
+          Slew load_slew;
+          arc_delay_calc->loadDelay(load_pin, wire_delay, load_slew);
+          delay = max(delay, gate_delay + wire_delay);
+          slew = max(slew, load_slew);
+        }
+      }
+    }
+    arc_delay_calc->finishDrvrPin();
+    parasitics->deleteParasitics(net, dcalc_ap->parasiticAnalysisPt());
+  }
+
+  // Cleanup the turds.
+  sta->deleteInstance(drvr);
+  sta->deleteInstance(load);
+  sta->deleteNet(net);
+  delete sta;
+  dbBlock::destroy(block);
+}
+
+void
+Resizer::makeWireParasitic(Net *net,
+                           Pin *drvr_pin,
+                           Pin *load_pin,
+                           double wire_length, // meters
+                           const Corner *corner,
+                           Parasitics *parasitics)
+{
+  const ParasiticAnalysisPt *parasitics_ap =
+    corner->findParasiticAnalysisPt(max_);
+  Parasitic *parasitic = parasitics->makeParasiticNetwork(net, false,
+                                                          parasitics_ap);
+  ParasiticNode *n1 = parasitics->ensureParasiticNode(parasitic, drvr_pin);
+  ParasiticNode *n2 = parasitics->ensureParasiticNode(parasitic, load_pin);
+  double wire_cap = wire_length * wireSignalCapacitance(corner);
+  double wire_res = wire_length * wireSignalResistance(corner);
+  parasitics->incrCap(n1, wire_cap / 2.0, parasitics_ap);
+  parasitics->makeResistor(nullptr, n1, n2, wire_res, parasitics_ap);
+  parasitics->incrCap(n2, wire_cap / 2.0, parasitics_ap);
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::findMaxSlewWireLength(LibertyPort *drvr_port,
+                               LibertyPort *load_port,
+                               double max_slew,
+                               const Corner *corner)
+{
+  ensureBlock();
+  // wire_length1 lower bound
+  // wire_length2 upper bound
+  double wire_length1 = 0.0;
+  double wire_length2 = std::sqrt(max_slew /(wireSignalResistance(corner)
+                                             * wireSignalCapacitance(corner)));
+  double tol = .01; // 1%
+  double diff1 = maxSlewWireDiff(drvr_port, load_port, wire_length2, max_slew);
+  // binary search for diff = 0.
+  while (abs(wire_length1 - wire_length2) > max(wire_length1, wire_length2) * tol) {
+    if (diff1 < 0.0) {
+      wire_length1 = wire_length2;
+      wire_length2 *= 2;
+      diff1 = maxSlewWireDiff(drvr_port, load_port, wire_length2, max_slew);
+    }
+    else {
+      double wire_length3 = (wire_length1 + wire_length2) / 2.0;
+      double diff2 = maxSlewWireDiff(drvr_port, load_port, wire_length3, max_slew);
+      if (diff2 < 0.0) {
+        wire_length1 = wire_length3;
+      }
+      else {
+        wire_length2 = wire_length3;
+        diff1 = diff2;
+      }
+    }
+  }
+  return wire_length1;
+}
+
+// objective function
+double
+Resizer::maxSlewWireDiff(LibertyPort *drvr_port,
+                         LibertyPort *load_port,
+                         double wire_length,
+                         double max_slew)
+{
+  Delay delay;
+  Slew slew;
+  cellWireDelay(drvr_port, load_port, wire_length, delay, slew);
+  return slew - max_slew;
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::designArea()
+{
+  ensureBlock();
+  ensureDesignArea();
+  return design_area_;
+}
+
+void
+Resizer::designAreaIncr(float delta)
+{
+  design_area_ += delta;
+}
+
+void
+Resizer::ensureDesignArea()
+{
+  if (block_) {
+    design_area_ = 0.0;
+    for (dbInst *inst : block_->getInsts()) {
+      dbMaster *master = inst->getMaster();
+      // Don't count fillers otherwise you'll always get 100% utilization
+      if (!master->isFiller()) {
+        design_area_ += area(master);
+      }
+    }
+  }
+}
+
+int
+Resizer::fanout(Pin *drvr_pin)
+{
+  int fanout = 0;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(drvr_pin);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (pin != drvr_pin)
+      fanout++;
+  }
+  delete pin_iter;
+  return fanout;
+}
+
+bool
+Resizer::isFuncOneZero(const Pin *drvr_pin)
+{
+  LibertyPort *port = network_->libertyPort(drvr_pin);
+  if (port) {
+    FuncExpr *func = port->function();
+    return func && (func->op() == FuncExpr::op_zero
+                    || func->op() == FuncExpr::op_one);
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::repairClkInverters()
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+  ensureBlock();
+  ensureDesignArea();
+  for (Instance *inv : findClkInverters())
+    cloneClkInverter(inv);
+}
+
+InstanceSeq
+Resizer::findClkInverters()
+{
+  InstanceSeq clk_inverters;
+  ClkArrivalSearchPred srch_pred(this);
+  BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
+  for (Clock *clk : sdc_->clks()) {
+    for (Pin *pin : clk->leafPins()) {
+      Vertex *vertex = graph_->pinDrvrVertex(pin);
+      bfs.enqueue(vertex);
+    }
+  }
+  while (bfs.hasNext()) {
+    Vertex *vertex = bfs.next();
+    const Pin *pin = vertex->pin();
+    Instance *inst = network_->instance(pin);
+    LibertyCell *lib_cell = network_->libertyCell(inst);
+    if (vertex->isDriver(network_)
+        && lib_cell
+        && lib_cell->isInverter()) {
+      clk_inverters.push_back(inst);
+      debugPrint(logger_, RSZ, "repair_clk_inverters", 2, "inverter {}",
+                 network_->pathName(inst));
+    }
+    if (!vertex->isRegClk())
+      bfs.enqueueAdjacentVertices(vertex);
+  }
+  return clk_inverters;
+}
+
+void
+Resizer::cloneClkInverter(Instance *inv)
+{
+  LibertyCell *inv_cell = network_->libertyCell(inv);
+  LibertyPort *in_port, *out_port;
+  inv_cell->bufferPorts(in_port, out_port);
+  Pin *in_pin = network_->findPin(inv, in_port);
+  Pin *out_pin = network_->findPin(inv, out_port);
+  Net *in_net = network_->net(in_pin);
+  dbNet *in_net_db = db_network_->staToDb(in_net);
+  Net *out_net = network_->isTopLevelPort(out_pin)
+    ? network_->net(network_->term(out_pin))
+    : network_->net(out_pin);
+  if (out_net) {
+    const char *inv_name = network_->name(inv);
+    Instance *top_inst = network_->topInstance();
+    NetConnectedPinIterator *load_iter = network_->pinIterator(out_net);
+    while (load_iter->hasNext()) {
+      Pin *load_pin = load_iter->next();
+      if (load_pin != out_pin) {
+        string clone_name = makeUniqueInstName(inv_name, true);
+        Instance *clone = sta_->makeInstance(clone_name.c_str(),
+                                             inv_cell, top_inst);
+        Point clone_loc = db_network_->location(load_pin);
+        journalMakeBuffer(clone);
+        setLocation(clone, clone_loc);
+
+        Net *clone_out_net = makeUniqueNet();
+        dbNet *clone_out_net_db = db_network_->staToDb(clone_out_net);
+        clone_out_net_db->setSigType(in_net_db->getSigType());
+
+        Instance *load = network_->instance(load_pin);
+        sta_->connectPin(clone, in_port, in_net);
+        sta_->connectPin(clone, out_port, clone_out_net);
+
+        // Connect load to clone
+        sta_->disconnectPin(load_pin);
+        Port *load_port = network_->port(load_pin);
+        sta_->connectPin(load, load_port, clone_out_net);
+      }
+    }
+    delete load_iter;
+
+    // Delete inv
+    sta_->disconnectPin(in_pin);
+    sta_->disconnectPin(out_pin);
+    sta_->deleteNet(out_net);
+    parasitics_invalid_.erase(out_net);
+    sta_->deleteInstance(inv);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Journal to roll back changes (OpenDB not up to the task).
+void
+Resizer::journalBegin()
+{
+  debugPrint(logger_, RSZ, "journal", 1, "journal begin");
+  resized_inst_map_.clear();
+  inserted_buffers_.clear();
+}
+
+void
+Resizer::journalInstReplaceCellBefore(Instance *inst)
+{
+  LibertyCell *lib_cell = network_->libertyCell(inst);
+  debugPrint(logger_, RSZ, "journal", 1, "journal replace {} ({})",
+             network_->pathName(inst),
+             lib_cell->name());
+  // Do not clobber an existing checkpoint cell.
+  if (!resized_inst_map_.hasKey(inst))
+    resized_inst_map_[inst] = lib_cell;
+}
+
+void
+Resizer::journalMakeBuffer(Instance *buffer)
+{
+  debugPrint(logger_, RSZ, "journal", 1, "journal make_buffer {}",
+             network_->pathName(buffer));
+  inserted_buffers_.insert(buffer);
+}
+
+void
+Resizer::journalRestore()
+{
+  for (auto inst_cell : resized_inst_map_) {
+    Instance *inst = inst_cell.first;
+    if (!inserted_buffers_.hasKey(inst)) {
+      LibertyCell *lib_cell = inst_cell.second;
+      debugPrint(logger_, RSZ, "journal", 1, "journal restore {} ({})",
+                 network_->pathName(inst),
+                 lib_cell->name());
+      replaceCell(inst, lib_cell, false);
+      resize_count_--;
+    }
+  }
+  for (Instance *buffer : inserted_buffers_) {
+    debugPrint(logger_, RSZ, "journal", 1, "journal remove {}",
+               network_->pathName(buffer));
+    removeBuffer(buffer);
+    inserted_buffer_count_--;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+class SteinerRenderer : public gui::Renderer
+{
+public:
+  SteinerRenderer();
+  void highlight(SteinerTree *tree);
+  virtual void drawObjects(gui::Painter& /* painter */) override;
+
+private:
+  SteinerTree *tree_;
+};
+
+void
+Resizer::highlightSteiner(const Pin *drvr)
+{
+  if (gui::Gui::enabled()) {
+    if (steiner_renderer_ == nullptr) {
+      steiner_renderer_ = new SteinerRenderer();
+      gui_->registerRenderer(steiner_renderer_);
+    }
+    SteinerTree *tree = nullptr;
+    if (drvr)
+      tree = makeSteinerTree(drvr, false, max_steiner_pin_count_,
+                             stt_builder_, db_network_, logger_);
+    steiner_renderer_->highlight(tree);
+  }
+}
+
+SteinerRenderer::SteinerRenderer() :
+  tree_(nullptr)
+{
+}
+
+void
+SteinerRenderer::highlight(SteinerTree *tree)
+{
+  tree_ = tree;
+}
+
+void
+SteinerRenderer::drawObjects(gui::Painter &painter)
+{
+  if (tree_) {
+    painter.setPen(gui::Painter::red, true);
+    for (int i = 0 ; i < tree_->branchCount(); ++i) {
+      Point pt1, pt2;
+      int steiner_pt1, steiner_pt2;
+      int wire_length;
+      tree_->branch(i, pt1, steiner_pt1, pt2, steiner_pt2, wire_length);
+      painter.drawLine(pt1, pt2);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+PinSet
+Resizer::findFaninFanouts(PinSet *end_pins)
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+
+  VertexSet ends;
+  for (Pin *pin : *end_pins) {
+    Vertex *end = graph_->pinLoadVertex(pin);
+    ends.insert(end);
+  }
+  PinSet fanin_fanout_pins;
+  VertexSet fanin_fanouts = findFaninFanouts(ends);
+  for (Vertex *vertex : fanin_fanouts)
+    fanin_fanout_pins.insert(vertex->pin());
+  return fanin_fanout_pins;
+}
+
+VertexSet
+Resizer::findFaninFanouts(VertexSet &ends)
+{
+  // Search backwards from ends to fanin register outputs and input ports.
+  VertexSet fanin_roots = findFaninRoots(ends);
+  // Search forward from register outputs.
+  VertexSet fanouts = findFanouts(fanin_roots);
+  return fanouts;
+}
+
+// Find source pins for logic fanin of ends.
+PinSet
+Resizer::findFanins(PinSet *end_pins)
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+
+  VertexSet ends;
+  for (Pin *pin : *end_pins) {
+    Vertex *end = graph_->pinLoadVertex(pin);
+    ends.insert(end);
+  }
+
+  SearchPredNonReg2 pred(sta_);
+  BfsBkwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *vertex : ends)
+    iter.enqueueAdjacentVertices(vertex);
+
+  PinSet fanins;
+  while (iter.hasNext()) {
+    Vertex *vertex = iter.next();
+    if (isRegOutput(vertex)
+        || network_->isTopLevelPort(vertex->pin()))
+      continue;
+    else {
+      iter.enqueueAdjacentVertices(vertex);
+      fanins.insert(vertex->pin());
+    }
+  }
+  return fanins;
+}
+
+// Find roots for logic fanin of ends.
+VertexSet
+Resizer::findFaninRoots(VertexSet &ends)
+{
+  SearchPredNonReg2 pred(sta_);
+  BfsBkwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *vertex : ends)
+    iter.enqueueAdjacentVertices(vertex);
+
+  VertexSet roots;
+  while (iter.hasNext()) {
+    Vertex *vertex = iter.next();
+    if (isRegOutput(vertex)
+        || network_->isTopLevelPort(vertex->pin()))
+      roots.insert(vertex);
+    else
+      iter.enqueueAdjacentVertices(vertex);
+  }
+  return roots;
+}
+
+bool
+Resizer::isRegOutput(Vertex *vertex)
+{
+  LibertyPort *port = network_->libertyPort(vertex->pin());
+  if (port) {
+    LibertyCell *cell = port->libertyCell();
+    LibertyCellTimingArcSetIterator arc_set_iter(cell, nullptr, port);
+    while (arc_set_iter.hasNext()) {
+      TimingArcSet *arc_set = arc_set_iter.next();
+      if (arc_set->role()->genericRole() == TimingRole::regClkToQ())
+        return true;
+    }
+  }
+  return false;
+}
+
+VertexSet
+Resizer::findFanouts(VertexSet &reg_outs)
+{
+  VertexSet fanouts;
+  sta::SearchPredNonLatch2 pred(sta_);
+  BfsFwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *reg_out : reg_outs)
+    iter.enqueueAdjacentVertices(reg_out);
+
+  while (iter.hasNext()) {
+    Vertex *vertex = iter.next();
+    if (!isRegister(vertex)) {
+      fanouts.insert(vertex);
+      iter.enqueueAdjacentVertices(vertex);
+    }
+  }
+  return fanouts;
+}
+
+bool
+Resizer::isRegister(Vertex *vertex)
+{
+  LibertyPort *port = network_->libertyPort(vertex->pin());
+  if (port) {
+    LibertyCell *cell = port->libertyCell();
+    return cell && cell->hasSequentials();
+  }
+  return false;
+}
+
+} // namespace
diff --git a/hacks/src/OpenSTA/network/ConcreteNetwork.cc b/hacks/src/OpenSTA/network/ConcreteNetwork.cc
new file mode 100644
index 0000000..8096f2e
--- /dev/null
+++ b/hacks/src/OpenSTA/network/ConcreteNetwork.cc
@@ -0,0 +1,1996 @@
+// OpenSTA, Static Timing Analyzer
+// Copyright (c) 2021, Parallax Software, Inc.
+// 
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+#include "ConcreteNetwork.hh"
+
+#include "DisallowCopyAssign.hh"
+#include "PatternMatch.hh"
+#include "Report.hh"
+#include "Liberty.hh"
+#include "PortDirection.hh"
+#include "ConcreteLibrary.hh"
+#include "Network.hh"
+
+namespace sta {
+
+static void
+makeChildNetwork(Instance *proto,
+		 Instance *parent,
+		 ConcreteBindingTbl *parent_bindings,
+		 NetworkReader *network);
+static void
+makeClonePins(Instance *proto,
+	      Instance *clone,
+	      Instance *clone_view,
+	      ConcreteBindingTbl *bindings,
+	      Instance *parent,
+	      ConcreteBindingTbl *parent_bindings,
+	      NetworkReader *network);
+
+NetworkReader *
+makeConcreteNetwork()
+{
+  return new ConcreteNetwork;
+}
+
+class ConcreteInstanceChildIterator : public InstanceChildIterator
+{
+public:
+  explicit ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map);
+  bool hasNext();
+  Instance *next();
+
+private:
+  ConcreteInstanceChildMap::ConstIterator iter_;
+};
+
+ConcreteInstanceChildIterator::
+ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map) :
+  iter_(map)
+{
+}
+
+bool
+ConcreteInstanceChildIterator::hasNext()
+{
+  return iter_.hasNext();
+}
+
+Instance *
+ConcreteInstanceChildIterator::next()
+{
+  return reinterpret_cast<Instance*>(iter_.next());
+}
+
+class ConcreteInstanceNetIterator : public InstanceNetIterator
+{
+public:
+  explicit ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets);
+  bool hasNext();
+  Net *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteInstanceNetIterator);
+  void findNext();
+
+  ConcreteInstanceNetMap::Iterator iter_;
+  ConcreteNet *next_;
+};
+
+ConcreteInstanceNetIterator::
+ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets):
+  iter_(nets),
+  next_(nullptr)
+{
+  findNext();
+}
+
+bool
+ConcreteInstanceNetIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+// Skip nets that have been merged.
+void
+ConcreteInstanceNetIterator::findNext()
+{
+  while (iter_.hasNext()) {
+    next_ = iter_.next();
+    if (next_->mergedInto() == nullptr)
+      return;
+  }
+  next_ = nullptr;
+}
+
+Net *
+ConcreteInstanceNetIterator::next()
+{
+  ConcreteNet *next = next_;
+  findNext();
+  return reinterpret_cast<Net*>(next);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteInstancePinIterator : public InstancePinIterator
+{
+public:
+  ConcreteInstancePinIterator(const ConcreteInstance *inst,
+			      int pin_count);
+  bool hasNext();
+  Pin *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteInstancePinIterator);
+  void findNext();
+
+  ConcretePin **pins_;
+  int pin_count_;
+  int pin_index_;
+  ConcretePin *next_;
+};
+
+ConcreteInstancePinIterator::
+ConcreteInstancePinIterator(const ConcreteInstance *inst,
+			    int pin_count) :
+  pins_(inst->pins_),
+  pin_count_(pin_count),
+  pin_index_(0)
+{
+  findNext();
+}
+
+bool
+ConcreteInstancePinIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+Pin *
+ConcreteInstancePinIterator::next()
+{
+  ConcretePin *next = next_;
+  findNext();
+  return reinterpret_cast<Pin*>(next);
+}
+
+// Skip over missing pins.
+void
+ConcreteInstancePinIterator::findNext()
+{
+  while (pin_index_ < pin_count_) {
+    next_ = pins_[pin_index_++];
+    if (next_)
+      return;
+  }
+  next_ = nullptr;
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteNetPinIterator : public NetPinIterator
+{
+public:
+  explicit ConcreteNetPinIterator(const ConcreteNet *net);
+  bool hasNext();
+  Pin *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteNetPinIterator);
+
+  ConcretePin *next_;
+};
+
+ConcreteNetPinIterator::ConcreteNetPinIterator(const ConcreteNet *net) :
+  next_(net->pins_)
+{
+}
+
+bool
+ConcreteNetPinIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+Pin *
+ConcreteNetPinIterator::next()
+{
+  ConcretePin *next = next_;
+  next_ = next_->net_next_;
+  return reinterpret_cast<Pin*>(next);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteNetTermIterator : public NetTermIterator
+{
+public:
+  explicit ConcreteNetTermIterator(const ConcreteNet *net);
+  bool hasNext();
+  Term *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteNetTermIterator);
+
+  ConcreteTerm *next_;
+};
+
+ConcreteNetTermIterator::ConcreteNetTermIterator(const ConcreteNet *net) :
+  next_(net->terms_)
+{
+}
+
+bool
+ConcreteNetTermIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+Term *
+ConcreteNetTermIterator::next()
+{
+  ConcreteTerm *next = next_;
+  next_ = next_->net_next_;
+  return reinterpret_cast<Term*>(next);
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteNetwork::ConcreteNetwork() :
+  NetworkReader(),
+  top_instance_(nullptr),
+  link_func_(nullptr)
+{
+}
+
+ConcreteNetwork::~ConcreteNetwork()
+{
+  clear();
+}
+
+void
+ConcreteNetwork::clear()
+{
+  deleteTopInstance();
+  deleteCellNetworkViews();
+  library_seq_.deleteContentsClear();
+  library_map_.clear();
+  Network::clear();
+}
+
+void
+ConcreteNetwork::deleteTopInstance()
+{
+  if (top_instance_) {
+    deleteInstance(top_instance_);
+    top_instance_ = nullptr;
+  }
+}
+
+void
+ConcreteNetwork::deleteCellNetworkViews()
+{
+  CellNetworkViewMap::Iterator view_iter(cell_network_view_map_);
+  while (view_iter.hasNext()) {
+    Instance *view = view_iter.next();
+    if (view)
+      deleteInstance(view);
+  }
+  cell_network_view_map_.clear();
+}
+
+Instance *
+ConcreteNetwork::topInstance() const
+{
+  return top_instance_;
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteLibraryIterator1 : public Iterator<Library*>
+{
+public:
+  explicit ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_);
+  virtual bool hasNext();
+  virtual Library *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteLibraryIterator1);
+
+  ConcreteLibraryIterator iter_;
+};
+
+ConcreteLibraryIterator1::ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_):
+  iter_(lib_seq_)
+{
+}
+
+bool
+ConcreteLibraryIterator1::hasNext()
+{
+  return iter_.hasNext();
+}
+
+Library *
+ConcreteLibraryIterator1::next()
+{
+  return reinterpret_cast<Library*>(iter_.next());
+}
+
+LibraryIterator *
+ConcreteNetwork::libraryIterator() const
+{
+  return new ConcreteLibraryIterator1(library_seq_);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteLibertyLibraryIterator : public Iterator<LibertyLibrary*>
+{
+public:
+  explicit ConcreteLibertyLibraryIterator(const ConcreteNetwork *network);
+  virtual ~ConcreteLibertyLibraryIterator();
+  virtual bool hasNext();
+  virtual LibertyLibrary *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteLibertyLibraryIterator);
+  void findNext();
+
+  ConcreteLibrarySeq::ConstIterator iter_;
+  LibertyLibrary *next_;
+};
+
+ConcreteLibertyLibraryIterator::
+ConcreteLibertyLibraryIterator(const ConcreteNetwork *network):
+  iter_(network->library_seq_),
+  next_(nullptr)
+{
+  findNext();
+}
+
+ConcreteLibertyLibraryIterator::~ConcreteLibertyLibraryIterator()
+{
+}
+
+bool
+ConcreteLibertyLibraryIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+LibertyLibrary *
+ConcreteLibertyLibraryIterator::next()
+{
+  LibertyLibrary *next = next_;
+  findNext();
+  return next;
+}
+
+void
+ConcreteLibertyLibraryIterator::findNext()
+{
+  next_ = nullptr;
+  while (iter_.hasNext()) {
+    ConcreteLibrary *lib = iter_.next();
+    if (lib->isLiberty()) {
+      LibertyLibrary *liberty = static_cast<LibertyLibrary*>(lib);
+      if (liberty) {
+	next_ = liberty;
+	break;
+      }
+    }
+  }
+}
+
+LibertyLibraryIterator *
+ConcreteNetwork::libertyLibraryIterator() const
+{
+  return new ConcreteLibertyLibraryIterator(this);
+}
+
+////////////////////////////////////////////////////////////////
+
+Library *
+ConcreteNetwork::makeLibrary(const char *name,
+			     const char *filename)
+{
+  ConcreteLibrary *library = new ConcreteLibrary(name, filename, false);
+  addLibrary(library);
+  return reinterpret_cast<Library*>(library);
+}
+
+LibertyLibrary *
+ConcreteNetwork::makeLibertyLibrary(const char *name,
+				    const char *filename)
+{
+  LibertyLibrary *library = new LibertyLibrary(name, filename);
+  addLibrary(library);
+  return library;
+}
+
+void
+ConcreteNetwork::addLibrary(ConcreteLibrary *library)
+{
+  library_seq_.push_back(library);
+  library_map_[library->name()] = library;
+}
+
+Library *
+ConcreteNetwork::findLibrary(const char *name)
+{
+  return reinterpret_cast<Library*>(library_map_.findKey(name));
+}
+
+void
+ConcreteNetwork::deleteLibrary(Library *library)
+{
+  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
+  library_map_.erase(clib->name());
+  library_seq_.eraseObject(clib);
+  delete clib;
+}
+
+const char *
+ConcreteNetwork::name(const Library *library) const
+{
+  const ConcreteLibrary *clib =
+    reinterpret_cast<const ConcreteLibrary*>(library);
+  return clib->name();
+}
+
+LibertyLibrary *
+ConcreteNetwork::findLiberty(const char *name)
+{
+  ConcreteLibrary *lib =  library_map_.findKey(name);
+  if (lib) {
+    if (lib->isLiberty())
+      return static_cast<LibertyLibrary*>(lib);
+    // Potential name conflict
+    else {
+      for (ConcreteLibrary *lib : library_seq_) {
+	if (stringEq(lib->name(), name)
+	    && lib->isLiberty())
+	  return static_cast<LibertyLibrary*>(lib);
+      }
+    }
+  }
+  return nullptr;
+}
+
+LibertyLibrary *
+ConcreteNetwork::libertyLibrary(Library *library) const
+{
+  ConcreteLibrary *lib = reinterpret_cast<ConcreteLibrary*>(library);
+  return static_cast<LibertyLibrary*>(lib);
+}
+
+Cell *
+ConcreteNetwork::makeCell(Library *library,
+			  const char *name,
+			  bool is_leaf,
+			  const char *filename)
+{
+  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
+  return reinterpret_cast<Cell*>(clib->makeCell(name, is_leaf, filename));
+}
+
+Cell *
+ConcreteNetwork::findCell(const Library *library,
+			  const char *name) const
+{
+  const ConcreteLibrary *clib =
+    reinterpret_cast<const ConcreteLibrary*>(library);
+  return reinterpret_cast<Cell*>(clib->findCell(name));
+}
+
+Cell *
+ConcreteNetwork::findAnyCell(const char *name)
+{
+  ConcreteLibrarySeq::Iterator lib_iter(library_seq_);
+  while (lib_iter.hasNext()) {
+    ConcreteLibrary *lib = lib_iter.next();
+    ConcreteCell *cell = lib->findCell(name);
+    if (cell)
+      return reinterpret_cast<Cell*>(cell);
+  }
+  return nullptr;
+}
+
+void
+ConcreteNetwork::findCellsMatching(const Library *library,
+				   const PatternMatch *pattern,
+				   CellSeq *cells) const
+{
+  const ConcreteLibrary *clib =
+    reinterpret_cast<const ConcreteLibrary*>(library);
+  clib->findCellsMatching(pattern, cells);
+}
+
+void
+ConcreteNetwork::deleteCell(Cell *cell)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcreteLibrary *clib = ccell->library();
+  clib->deleteCell(ccell);
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->name();
+}
+
+void
+ConcreteNetwork::setName(Cell *cell,
+			 const char *name)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ccell->setName(name);
+}
+
+void
+ConcreteNetwork::setIsLeaf(Cell *cell,
+			   bool is_leaf)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ccell->setIsLeaf(is_leaf);
+}
+
+Library *
+ConcreteNetwork::library(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return reinterpret_cast<Library*>(ccell->library());
+}
+
+LibertyCell *
+ConcreteNetwork::libertyCell(Cell *cell) const
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  return ccell->libertyCell();
+}
+
+const LibertyCell *
+ConcreteNetwork::libertyCell(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->libertyCell();
+}
+
+Cell *
+ConcreteNetwork::cell(LibertyCell *cell) const
+{
+  return reinterpret_cast<Cell*>(cell);
+}
+
+const Cell *
+ConcreteNetwork::cell(const LibertyCell *cell) const
+{
+  return reinterpret_cast<const Cell*>(cell);
+}
+
+const char *
+ConcreteNetwork::filename(const Cell *cell)
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->filename();
+}
+
+Port *
+ConcreteNetwork::findPort(const Cell *cell,
+			  const char *name) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return reinterpret_cast<Port*>(ccell->findPort(name));
+}
+
+void
+ConcreteNetwork::findPortsMatching(const Cell *cell,
+				   const PatternMatch *pattern,
+				   PortSeq *ports) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  ccell->findPortsMatching(pattern, ports);
+}
+
+bool
+ConcreteNetwork::isLeaf(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->isLeaf();
+}
+
+Port *
+ConcreteNetwork::makePort(Cell *cell,
+			  const char *name)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcretePort *port = ccell->makePort(name);
+  return reinterpret_cast<Port*>(port);
+}
+
+Port *
+ConcreteNetwork::makeBusPort(Cell *cell,
+			     const char *name,
+			     int from_index,
+			     int to_index)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcretePort *port = ccell->makeBusPort(name, from_index, to_index);
+  return reinterpret_cast<Port*>(port);
+}
+
+void
+ConcreteNetwork::groupBusPorts(Cell *cell,
+                               std::function<bool(const char*)> port_msb_first)
+{
+  Library *lib = library(cell);
+  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(lib);
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ccell->groupBusPorts(clib->busBrktLeft(), clib->busBrktRight(), port_msb_first);
+}
+
+Port *
+ConcreteNetwork::makeBundlePort(Cell *cell,
+				const char *name,
+				PortSeq *members)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcretePortSeq *cmembers = reinterpret_cast<ConcretePortSeq*>(members);
+  ConcretePort *port = ccell->makeBundlePort(name, cmembers);
+  return reinterpret_cast<Port*>(port);
+}
+
+void
+ConcreteNetwork::setDirection(Port *port,
+			      PortDirection *dir)
+{
+  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
+  cport->setDirection(dir);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteCellPortIterator1 : public CellPortIterator
+{
+public:
+  explicit ConcreteCellPortIterator1(const ConcreteCell *cell);
+  ~ConcreteCellPortIterator1();
+  virtual bool hasNext() { return iter_->hasNext(); }
+  virtual Port *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortIterator1);
+
+  ConcreteCellPortIterator *iter_;
+};
+
+ConcreteCellPortIterator1::ConcreteCellPortIterator1(const ConcreteCell *cell):
+  iter_(cell->portIterator())
+{
+}
+
+ConcreteCellPortIterator1::~ConcreteCellPortIterator1()
+{
+  delete iter_;
+}
+
+Port *
+ConcreteCellPortIterator1::next()
+{
+  return reinterpret_cast<Port*>(iter_->next());
+}
+
+CellPortIterator *
+ConcreteNetwork::portIterator(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return new ConcreteCellPortIterator1(ccell);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteCellPortBitIterator1 : public CellPortIterator
+{
+public:
+  explicit ConcreteCellPortBitIterator1(const ConcreteCell *cell);
+  ~ConcreteCellPortBitIterator1();
+  virtual bool hasNext() { return iter_->hasNext(); }
+  virtual Port *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortBitIterator1);
+
+  ConcreteCellPortBitIterator *iter_;
+};
+
+ConcreteCellPortBitIterator1::ConcreteCellPortBitIterator1(const ConcreteCell *cell):
+  iter_(cell->portBitIterator())
+{
+}
+
+ConcreteCellPortBitIterator1::~ConcreteCellPortBitIterator1()
+{
+  delete iter_;
+}
+
+Port *
+ConcreteCellPortBitIterator1::next()
+{
+  return reinterpret_cast<Port*>(iter_->next());
+}
+
+CellPortBitIterator *
+ConcreteNetwork::portBitIterator(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return new ConcreteCellPortBitIterator1(ccell);
+}
+
+int
+ConcreteNetwork::portBitCount(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->portBitCount();
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->name();
+}
+
+Cell *
+ConcreteNetwork::cell(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->cell();
+}
+
+LibertyPort *
+ConcreteNetwork::libertyPort(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->libertyPort();
+}
+
+PortDirection *
+ConcreteNetwork::direction(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->direction();
+}
+
+bool
+ConcreteNetwork::isBundle(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->isBundle();
+}
+
+bool
+ConcreteNetwork::isBus(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->isBus();
+}
+
+const char *
+ConcreteNetwork::busName(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->busName();
+}
+
+int
+ConcreteNetwork::size(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->size();
+}
+
+int
+ConcreteNetwork::fromIndex(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->fromIndex();
+}
+
+int
+ConcreteNetwork::toIndex(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->toIndex();
+}
+
+Port *
+ConcreteNetwork::findBusBit(const Port *port,
+			    int index) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return reinterpret_cast<Port*>(cport->findBusBit(index));
+}
+
+Port *
+ConcreteNetwork::findMember(const Port *port,
+			    int index) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return reinterpret_cast<Port*>(cport->findMember(index));
+}
+
+bool
+ConcreteNetwork::hasMembers(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->hasMembers();
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcretePortMemberIterator1 : public PortMemberIterator
+{
+public:
+  explicit ConcretePortMemberIterator1(const ConcretePort *port);
+  ~ConcretePortMemberIterator1();
+  virtual bool hasNext() { return iter_->hasNext(); }
+  virtual Port *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcretePortMemberIterator1);
+
+  ConcretePortMemberIterator *iter_;
+};
+
+ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort *
+							 port) :
+  iter_(port->memberIterator())
+{
+}
+
+ConcretePortMemberIterator1::~ConcretePortMemberIterator1()
+{
+  delete iter_;
+}
+
+Port *
+ConcretePortMemberIterator1::next()
+{
+  return reinterpret_cast<Port*>(iter_->next());
+}
+
+PortMemberIterator *
+ConcreteNetwork::memberIterator(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return new ConcretePortMemberIterator1(cport);
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->name();
+}
+
+Cell *
+ConcreteNetwork::cell(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->cell();
+}
+
+Instance *
+ConcreteNetwork::parent(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Instance*>(inst->parent());
+}
+
+bool
+ConcreteNetwork::isLeaf(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(inst->cell());
+  return ccell->isLeaf();
+}
+
+Instance *
+ConcreteNetwork::findChild(const Instance *parent,
+			   const char *name) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(parent);
+  return inst->findChild(name);
+}
+
+Pin *
+ConcreteNetwork::findPin(const Instance *instance,
+			 const char *port_name) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Pin*>(inst->findPin(port_name));
+}
+
+Pin *
+ConcreteNetwork::findPin(const Instance *instance,
+			 const Port *port) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Pin*>(inst->findPin(port));
+}
+
+Net *
+ConcreteNetwork::findNet(const Instance *instance,
+			 const char *net_name) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Net*>(inst->findNet(net_name));
+}
+
+void
+ConcreteNetwork::findInstNetsMatching(const Instance *instance,
+				      const PatternMatch *pattern,
+				      NetSeq *nets) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  inst->findNetsMatching(pattern, nets);
+}
+
+////////////////////////////////////////////////////////////////
+
+InstanceChildIterator *
+ConcreteNetwork::childIterator(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->childIterator();
+}
+
+InstancePinIterator *
+ConcreteNetwork::pinIterator(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  ConcreteCell *cell = reinterpret_cast<ConcreteCell*>(inst->cell());
+  int pin_count = cell->portBitCount();
+  return new ConcreteInstancePinIterator(inst, pin_count);
+}
+
+InstanceNetIterator *
+ConcreteNetwork::netIterator(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->netIterator();
+}
+
+////////////////////////////////////////////////////////////////
+
+Instance *
+ConcreteNetwork::instance(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Instance*>(cpin->instance());
+}
+
+Net *
+ConcreteNetwork::net(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Net*>(cpin->net());
+}
+
+Term *
+ConcreteNetwork::term(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Term*>(cpin->term());
+}
+
+Port *
+ConcreteNetwork::port(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Port*>(cpin->port());
+}
+
+PortDirection *
+ConcreteNetwork::direction(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  const ConcretePort *cport = cpin->port();
+  return cport->direction();
+}
+
+VertexId
+ConcreteNetwork::vertexId(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return cpin->vertexId();
+}
+
+void
+ConcreteNetwork::setVertexId(Pin *pin,
+			     VertexId id)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  cpin->setVertexId(id);
+}
+
+////////////////////////////////////////////////////////////////
+
+Net *
+ConcreteNetwork::net(const Term *term) const
+{
+  const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
+  return reinterpret_cast<Net*>(cterm->net());
+}
+
+Pin *
+ConcreteNetwork::pin(const Term *term) const
+{
+  const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
+  return reinterpret_cast<Pin*>(cterm->pin());
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return cnet->name();
+}
+
+Instance *
+ConcreteNetwork::instance(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return reinterpret_cast<Instance*>(cnet->instance());
+}
+
+bool
+ConcreteNetwork::isPower(const Net *net) const
+{
+  return constant_nets_[int(LogicValue::one)].hasKey(const_cast<Net*>(net));
+}
+
+bool
+ConcreteNetwork::isGround(const Net *net) const
+{
+  return constant_nets_[int(LogicValue::zero)].hasKey(const_cast<Net*>(net));
+}
+
+NetPinIterator *
+ConcreteNetwork::pinIterator(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return new ConcreteNetPinIterator(cnet);
+}
+
+NetTermIterator *
+ConcreteNetwork::termIterator(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return new ConcreteNetTermIterator(cnet);
+}
+
+void
+ConcreteNetwork::mergeInto(Net *net,
+			   Net *into_net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteNet *cinto_net = reinterpret_cast<ConcreteNet*>(into_net);
+  cnet->mergeInto(cinto_net);
+  clearNetDrvrPinMap();
+}
+
+Net *
+ConcreteNetwork::mergedInto(Net *net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  return reinterpret_cast<Net*>(cnet->mergedInto());
+}
+
+////////////////////////////////////////////////////////////////
+
+Cell *
+ConcreteInstance::cell() const
+{
+  return reinterpret_cast<Cell*>(cell_);
+}
+
+Instance *
+ConcreteNetwork::makeInstance(Cell *cell,
+			      const char *name,
+			      Instance *parent)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  return makeConcreteInstance(ccell, name, parent);
+}
+
+Instance *
+ConcreteNetwork::makeInstance(LibertyCell *cell,
+			      const char *name,
+			      Instance *parent)
+{
+  return makeConcreteInstance(cell, name, parent);
+}
+
+Instance *
+ConcreteNetwork::makeConcreteInstance(ConcreteCell *cell,
+				      const char *name,
+				      Instance *parent)
+{
+  ConcreteInstance *cparent =
+    reinterpret_cast<ConcreteInstance*>(parent);
+  ConcreteInstance *inst = new ConcreteInstance(cell, name, cparent);
+  if (parent)
+    cparent->addChild(inst);
+  return reinterpret_cast<Instance*>(inst);
+}
+
+void
+ConcreteNetwork::makePins(Instance *inst)
+{
+  CellPortBitIterator *port_iterator = portBitIterator(cell(inst));
+  while (port_iterator->hasNext()) {
+    Port *port = port_iterator->next();
+    makePin(inst, port, nullptr);
+  }
+  delete port_iterator;
+}
+
+void
+ConcreteNetwork::replaceCell(Instance *inst,
+			     Cell *cell)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  int port_count = ccell->portBitCount();
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+  // Port count picked from Instance instead of Target cells-Dinesh A
+  ConcreteCell *instcell = reinterpret_cast<ConcreteCell*>(cinst->cell());
+  int inst_port_count = instcell->portBitCount();
+  ConcretePin **pins = cinst->pins_;
+  ConcretePin **rpins = new ConcretePin*[port_count];
+  for (int i = 0; i < port_count; i++) 
+    rpins[i] = pins[inst_port_count-1];
+  for (int i = 0; i < inst_port_count; i++) {
+    ConcretePin *cpin = pins[i];
+    if (cpin) {
+      ConcretePort *pin_cport = reinterpret_cast<ConcretePort*>(cpin->port());
+      ConcretePort *cport = ccell->findPort(pin_cport->name());
+      rpins[cport->pinIndex()] = cpin;
+      cpin->port_ = cport;
+    }
+  }
+  delete [] pins;
+  cinst->pins_ = rpins;
+  cinst->setCell(ccell);
+}
+
+void
+ConcreteNetwork::deleteInstance(Instance *inst)
+{
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+
+  // Delete nets first (so children pin deletes are not required).
+  ConcreteInstanceNetMap::Iterator net_iter(cinst->nets_);
+  while (net_iter.hasNext()) {
+    ConcreteNet *cnet = net_iter.next();
+    Net *net = reinterpret_cast<Net*>(cnet);
+    // Delete terminals connected to net.
+    NetTermIterator *term_iter = termIterator(net);
+    while (term_iter->hasNext()) {
+      ConcreteTerm *term = reinterpret_cast<ConcreteTerm*>(term_iter->next());
+      delete term;
+    }
+    delete term_iter;
+    deleteNet(net);
+  }
+
+  // Delete children.
+  InstanceChildIterator *child_iter = childIterator(inst);
+  while (child_iter->hasNext()) {
+    Instance *child = child_iter->next();
+    deleteInstance(child);
+  }
+  delete child_iter;
+
+  InstancePinIterator *pin_iter = pinIterator(inst);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    deletePin(pin);
+  }
+  delete pin_iter;
+
+  Instance *parent_inst = parent(inst);
+  if (parent_inst) {
+    ConcreteInstance *cparent =
+      reinterpret_cast<ConcreteInstance*>(parent_inst);
+    cparent->deleteChild(cinst);
+  }
+  delete cinst;
+}
+
+Pin *
+ConcreteNetwork::makePin(Instance *inst,
+			 Port *port,
+			 Net *net)
+{
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcretePin *cpin = new ConcretePin(cinst, cport, cnet);
+  cinst->addPin(cpin);
+  if (cnet)
+    connectNetPin(cnet, cpin);
+  return reinterpret_cast<Pin*>(cpin);
+}
+
+Term *
+ConcreteNetwork::makeTerm(Pin *pin,
+			  Net *net)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
+  if (cnet)
+    cnet->addTerm(cterm);
+  cpin->term_ = cterm;
+  return reinterpret_cast<Term*>(cterm);
+}
+
+Pin *
+ConcreteNetwork::connect(Instance *inst,
+			 LibertyPort *port,
+			 Net *net)
+{
+  return connect(inst, reinterpret_cast<Port*>(port), net);
+}
+
+Pin *
+ConcreteNetwork::connect(Instance *inst,
+			 Port *port,
+			 Net *net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
+  ConcretePin *cpin = cinst->findPin(port);
+  if (cpin) {
+    ConcreteNet *prev_net = cpin->net_;
+    if (prev_net)
+      disconnectNetPin(prev_net, cpin);
+  }
+  else {
+    cpin = new ConcretePin(cinst, cport, cnet);
+    cinst->addPin(cpin);
+  }
+  if (inst == top_instance_) {
+    // makeTerm
+    ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
+    cnet->addTerm(cterm);
+    cpin->term_ = cterm;
+    cpin->net_ = nullptr;
+  }
+  else {
+    cpin->net_ = cnet;
+    connectNetPin(cnet, cpin);
+  }
+  return reinterpret_cast<Pin*>(cpin);
+}
+
+void
+ConcreteNetwork::connectNetPin(ConcreteNet *cnet,
+			       ConcretePin *cpin)
+{
+  cnet->addPin(cpin);
+
+  // If there are no terminals the net does not span hierarchy levels
+  // and it is safe to incrementally update the drivers.
+  Pin *pin = reinterpret_cast<Pin*>(cpin);
+  if (isDriver(pin)) {
+    if (cnet->terms_ == nullptr) {
+      Net *net = reinterpret_cast<Net*>(cnet);
+      PinSet *drvrs = net_drvr_pin_map_.findKey(net);
+      if (drvrs)
+	drvrs->insert(pin);
+    }
+    else
+      clearNetDrvrPinMap();
+  }
+}
+
+void
+ConcreteNetwork::disconnectPin(Pin *pin)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  if (reinterpret_cast<Instance*>(cpin->instance()) == top_instance_) {
+    ConcreteTerm *cterm = cpin->term_;
+    if (cterm) {
+      ConcreteNet *cnet = cterm->net_;
+      if (cnet) {
+	cnet->deleteTerm(cterm);
+	clearNetDrvrPinMap();
+      }
+      cpin->term_ = nullptr;
+      delete cterm;
+    }
+  }
+  else {
+    ConcreteNet *cnet = cpin->net();
+    if (cnet)
+      disconnectNetPin(cnet, cpin);
+    cpin->net_ = nullptr;
+  }
+}
+
+void
+ConcreteNetwork::disconnectNetPin(ConcreteNet *cnet,
+				  ConcretePin *cpin)
+{
+  cnet->deletePin(cpin);
+
+  Pin *pin = reinterpret_cast<Pin*>(cpin);
+  if (isDriver(pin)) {
+    ConcreteNet *cnet = cpin->net();
+    // If there are no terminals the net does not span hierarchy levels
+    // and it is safe to incrementally update the drivers.
+    if (cnet->terms_ == nullptr) {
+      Net *net = reinterpret_cast<Net*>(cnet);
+      PinSet *drvrs = net_drvr_pin_map_.findKey(net);
+      if (drvrs)
+	drvrs->erase(pin);
+    }
+    else
+      clearNetDrvrPinMap();
+  }
+}
+
+void
+ConcreteNetwork::deletePin(Pin *pin)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  ConcreteNet *cnet = cpin->net();
+  if (cnet)
+    disconnectNetPin(cnet, cpin);
+  ConcreteInstance *cinst =
+    reinterpret_cast<ConcreteInstance*>(cpin->instance());
+  if (cinst)
+    cinst->deletePin(cpin);
+  delete cpin;
+}
+
+Net *
+ConcreteNetwork::makeNet(const char *name,
+			 Instance *parent)
+{
+  ConcreteInstance *cparent = reinterpret_cast<ConcreteInstance*>(parent);
+  ConcreteNet *net = new ConcreteNet(name, cparent);
+  cparent->addNet(net);
+  return reinterpret_cast<Net*>(net);
+}
+
+void
+ConcreteNetwork::deleteNet(Net *net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteNetPinIterator pin_iter(cnet);
+  while (pin_iter.hasNext()) {
+    ConcretePin *pin = reinterpret_cast<ConcretePin*>(pin_iter.next());
+    // Do NOT use net->disconnectPin because it would be N^2
+    // to delete all of the pins from the net.
+    pin->net_ = nullptr;
+  }
+
+  constant_nets_[int(LogicValue::zero)].erase(net);
+  constant_nets_[int(LogicValue::one)].erase(net);
+  PinSet *drvrs = net_drvr_pin_map_.findKey(net);
+  if (drvrs) {
+    delete drvrs;
+    net_drvr_pin_map_.erase(net);
+  }
+
+  ConcreteInstance *cinst =
+    reinterpret_cast<ConcreteInstance*>(cnet->instance());
+  cinst->deleteNet(cnet);
+  delete cnet;
+}
+
+void
+ConcreteNetwork::clearConstantNets()
+{
+  constant_nets_[int(LogicValue::zero)].clear();
+  constant_nets_[int(LogicValue::one)].clear();
+}
+
+void
+ConcreteNetwork::addConstantNet(Net *net,
+				LogicValue value)
+{
+  constant_nets_[int(value)].insert(net);
+}
+
+ConstantPinIterator *
+ConcreteNetwork::constantPinIterator()
+{
+  return new NetworkConstantPinIterator(this,
+					constant_nets_[int(LogicValue::zero)],
+					constant_nets_[int(LogicValue::one)]);
+}
+
+////////////////////////////////////////////////////////////////
+
+// Optimized version of Network::visitConnectedPins.
+void
+ConcreteNetwork::visitConnectedPins(const Net *net,
+				    PinVisitor &visitor,
+				    ConstNetSet &visited_nets) const
+{
+  if (!visited_nets.hasKey(net)) {
+    visited_nets.insert(net);
+    // Search up from net terminals.
+    const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+    for (ConcreteTerm *term = cnet->terms_; term; term = term->net_next_) {
+      ConcretePin *above_pin = term->pin_;
+      if (above_pin) {
+	ConcreteNet *above_net = above_pin->net_;
+	if (above_net)
+	  visitConnectedPins(reinterpret_cast<Net*>(above_net),
+			     visitor, visited_nets);
+	else
+	  visitor(reinterpret_cast<Pin*>(above_pin));
+      }
+    }
+
+    // Search down from net pins.
+    for (ConcretePin *pin = cnet->pins_; pin; pin = pin->net_next_) {
+      visitor(reinterpret_cast<Pin*>(pin));
+      ConcreteTerm *below_term = pin->term_;
+      if (below_term) {
+	ConcreteNet *below_net = below_term->net_;
+	if (below_net)
+	  visitConnectedPins(reinterpret_cast<Net*>(below_net),
+			     visitor, visited_nets);
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteInstance::ConcreteInstance(ConcreteCell *cell,
+				   const char *name,
+				   ConcreteInstance *parent) :
+  cell_(cell),
+  name_(stringCopy(name)),
+  parent_(parent),
+  children_(nullptr),
+  nets_(nullptr)
+{
+  initPins();
+}
+
+void
+ConcreteInstance::initPins()
+{
+  int pin_count = reinterpret_cast<ConcreteCell*>(cell_)->portBitCount();
+  if (pin_count) {
+    pins_ = new ConcretePin*[pin_count];
+    for (int i = 0; i < pin_count; i++)
+      pins_[i] = nullptr;
+  }
+  else
+    pins_ = nullptr;
+}
+
+ConcreteInstance::~ConcreteInstance()
+{
+  stringDelete(name_);
+  delete [] pins_;
+  delete children_;
+  delete nets_;
+}
+
+Instance *
+ConcreteInstance::findChild(const char *name) const
+{
+  if (children_)
+    return reinterpret_cast<Instance*>(children_->findKey(name));
+  else
+    return nullptr;
+}
+
+ConcretePin *
+ConcreteInstance::findPin(const char *port_name) const
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell_);
+  const ConcretePort *cport =
+    reinterpret_cast<const ConcretePort*>(ccell->findPort(port_name));
+  if (cport
+      && !cport->isBus())
+    return pins_[cport->pinIndex()];
+  else
+    return nullptr;
+}
+
+ConcretePin *
+ConcreteInstance::findPin(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return pins_[cport->pinIndex()];
+}
+
+ConcreteNet *
+ConcreteInstance::findNet(const char *net_name) const
+{
+  ConcreteNet *net = nullptr;
+  if (nets_) {
+    net = nets_->findKey(net_name);
+    // Follow merge pointer to surviving net.
+    if (net) {
+      while (net->mergedInto())
+	net = net->mergedInto();
+    }
+  }
+  return net;
+}
+
+void
+ConcreteInstance::findNetsMatching(const PatternMatch *pattern,
+				   NetSeq *nets) const
+{
+  if (pattern->hasWildcards()) {
+    ConcreteInstanceNetMap::Iterator net_iter(nets_);
+    while (net_iter.hasNext()) {
+      const char *net_name;
+      ConcreteNet *cnet;
+      net_iter.next(net_name, cnet);
+      if (pattern->match(net_name))
+	nets->push_back(reinterpret_cast<Net*>(cnet));
+    }
+  }
+  else {
+    ConcreteNet *cnet = findNet(pattern->pattern());
+    if (cnet)
+      nets->push_back(reinterpret_cast<Net*>(cnet));
+  }
+}
+
+InstanceNetIterator *
+ConcreteInstance::netIterator() const
+{
+  return reinterpret_cast<InstanceNetIterator*>
+    (new ConcreteInstanceNetIterator(nets_));
+}
+
+InstanceChildIterator *
+ConcreteInstance::childIterator() const
+{
+  return new ConcreteInstanceChildIterator(children_);
+}
+
+void
+ConcreteInstance::addChild(ConcreteInstance *child)
+{
+  if (children_ == nullptr)
+    children_ = new ConcreteInstanceChildMap;
+  (*children_)[child->name()] = child;
+}
+
+void
+ConcreteInstance::deleteChild(ConcreteInstance *child)
+{
+  children_->erase(child->name());
+}
+
+void
+ConcreteInstance::addPin(ConcretePin *pin)
+{
+  ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
+  pins_[cport->pinIndex()] = pin;
+}
+
+void
+ConcreteInstance::deletePin(ConcretePin *pin)
+{
+  ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
+  pins_[cport->pinIndex()] = nullptr;
+}
+
+void
+ConcreteInstance::addNet(ConcreteNet *net)
+{
+  if (nets_ == nullptr)
+    nets_ = new ConcreteInstanceNetMap;
+  (*nets_)[net->name()] = net;
+}
+
+void
+ConcreteInstance::addNet(const char *name,
+			 ConcreteNet *net)
+{
+  if (nets_ == nullptr)
+    nets_ = new ConcreteInstanceNetMap;
+  (*nets_)[name] = net;
+}
+
+void
+ConcreteInstance::deleteNet(ConcreteNet *net)
+{
+  nets_->erase(net->name());
+}
+
+void
+ConcreteInstance::setCell(ConcreteCell *cell)
+{
+  cell_ = cell;
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcretePin::ConcretePin(ConcreteInstance *instance,
+			 ConcretePort *port,
+			 ConcreteNet *net) :
+  instance_(instance),
+  port_(port),
+  net_(net),
+  term_(nullptr),
+  net_next_(nullptr),
+  net_prev_(nullptr),
+  vertex_id_(vertex_id_null)
+{
+}
+
+const char *
+ConcretePin::name() const
+{
+  return port_->name();
+}
+
+void
+ConcretePin::setVertexId(VertexId id)
+{
+  vertex_id_ = id;
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteTerm::name() const
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin_);
+  const ConcretePort *cport =
+    reinterpret_cast<const ConcretePort*>(cpin->port());
+  return cport->name();
+}
+
+ConcreteTerm::ConcreteTerm(ConcretePin *pin,
+			   ConcreteNet *net) :
+  pin_(pin),
+  net_(net),
+  net_next_(nullptr)
+{
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteNet::ConcreteNet(const char *name,
+			 ConcreteInstance *instance) :
+  name_(stringCopy(name)),
+  instance_(instance),
+  pins_(nullptr),
+  terms_(nullptr),
+  merged_into_(nullptr)
+{
+}
+
+ConcreteNet::~ConcreteNet()
+{
+  stringDelete(name_);
+}
+
+// Merged nets are kept around to serve as name aliases.
+// Only Instance::findNet and InstanceNetIterator need to know
+// the net has been merged.
+void
+ConcreteNet::mergeInto(ConcreteNet *net)
+{
+  ConcreteNetPinIterator pin_iter(this);
+  while (pin_iter.hasNext()) {
+    Pin *pin = pin_iter.next();
+    ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+    net->addPin(cpin);
+    cpin->net_ = net;
+  }
+  pins_ = nullptr;
+  ConcreteNetTermIterator term_iter(this);
+  while (term_iter.hasNext()) {
+    Term *term = term_iter.next();
+    ConcreteTerm *cterm = reinterpret_cast<ConcreteTerm*>(term);
+    net->addTerm(cterm);
+    cterm->net_ = net;
+  }
+  terms_ = nullptr;
+  // Leave name map pointing to merged net because otherwise a top
+  // level merged net has no pointer to it and it is leaked.
+  merged_into_ = net;
+}
+
+void
+ConcreteNet::addPin(ConcretePin *pin)
+{
+  if (pins_)
+    pins_->net_prev_ = pin;
+  pin->net_next_ = pins_;
+  pin->net_prev_ = nullptr;
+  pins_ = pin;
+}
+
+void
+ConcreteNet::deletePin(ConcretePin *pin)
+{
+  ConcretePin *prev = pin->net_prev_;
+  ConcretePin *next = pin->net_next_;
+  if (prev)
+    prev->net_next_ = next;
+  if (next)
+    next->net_prev_ = prev;
+  if (pins_ == pin)
+    pins_ = next;
+}
+
+void
+ConcreteNet::addTerm(ConcreteTerm *term)
+{
+  ConcreteTerm *next = terms_;
+  terms_ = term;
+  term->net_next_ = next;
+}
+
+void
+ConcreteNet::deleteTerm(ConcreteTerm *term)
+{
+  ConcreteTerm *net_prev_term = nullptr;
+  for (ConcreteTerm *net_term=terms_;net_term;net_term=net_term->net_next_) {
+    if (net_term == term) {
+      if (net_prev_term)
+	net_prev_term->net_next_ = term->net_next_;
+      else
+	terms_ = term->net_next_;
+      break;
+    }
+    net_prev_term = net_term;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+typedef Map<Net*, Net*> BindingMap;
+
+// Binding table used for linking/expanding network.
+class ConcreteBindingTbl
+{
+public:
+  explicit ConcreteBindingTbl(NetworkEdit *network);
+  Net *ensureBinding(Net *proto_net,
+		     Instance *parent);
+  Net *find(Net *net);
+  void bind(Net *proto_net,
+	    Net *clone_net);
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteBindingTbl);
+
+  BindingMap map_;
+  NetworkEdit *network_;
+};
+
+void
+ConcreteNetwork::setCellNetworkView(Cell *cell,
+				    Instance *inst)
+{
+  cell_network_view_map_[cell] = inst;
+}
+
+Instance *
+ConcreteNetwork::cellNetworkView(Cell *cell)
+{
+  return cell_network_view_map_.findKey(cell);
+}
+
+void
+ConcreteNetwork::readNetlistBefore()
+{
+  clearConstantNets();
+  deleteTopInstance();
+  clearNetDrvrPinMap();
+}
+
+void
+ConcreteNetwork::setTopInstance(Instance *top_inst)
+{
+  if (top_instance_) {
+    deleteInstance(top_instance_);
+    clearConstantNets();
+    clearNetDrvrPinMap();
+  }
+  top_instance_ = top_inst;
+}
+
+void
+ConcreteNetwork::setLinkFunc(LinkNetworkFunc *link)
+{
+  link_func_ = link;
+}
+
+bool
+ConcreteNetwork::linkNetwork(const char *top_cell_name,
+			     bool make_black_boxes,
+			     Report *report)
+{
+  if (link_func_) {
+    clearConstantNets();
+    deleteTopInstance();
+    top_instance_ = link_func_(top_cell_name, make_black_boxes, report, this);
+    return top_instance_ != nullptr;
+  }
+  else {
+    report->error(8, "cell type %s can not be linked.", top_cell_name);
+    return false;
+  }
+}
+
+Instance *
+linkReaderNetwork(Cell *top_cell,
+		  bool, Report *,
+		  NetworkReader *network)
+{
+  Instance *view = network->cellNetworkView(top_cell);
+  if (view) {
+    // Seed the recursion for expansion with the top level instance.
+    Instance *top_instance = network->makeInstance(top_cell, "", nullptr);
+    ConcreteBindingTbl bindings(network);
+    makeClonePins(view, top_instance, view, &bindings, nullptr, nullptr, network);
+    InstanceChildIterator *child_iter = network->childIterator(view);
+    while (child_iter->hasNext()) {
+      Instance *child = child_iter->next();
+      makeChildNetwork(child, top_instance, &bindings, network);
+    }
+    delete child_iter;
+    network->deleteCellNetworkViews();
+    return top_instance;
+  }
+  return nullptr;
+}
+
+static void
+makeChildNetwork(Instance *proto,
+		 Instance *parent,
+		 ConcreteBindingTbl *parent_bindings,
+		 NetworkReader *network)
+{
+  Cell *proto_cell = network->cell(proto);
+  Instance *clone = network->makeInstance(proto_cell, network->name(proto),
+					  parent);
+  if (network->isLeaf(proto_cell))
+    makeClonePins(proto, clone, nullptr, nullptr, parent, parent_bindings, network);
+  else {
+    // Recurse if this isn't a leaf cell.
+    ConcreteBindingTbl bindings(network);
+    Instance *clone_view = network->cellNetworkView(proto_cell);
+    makeClonePins(proto, clone, clone_view, &bindings, parent,
+		  parent_bindings, network);
+    if (clone_view) {
+      InstanceChildIterator *child_iter = network->childIterator(clone_view);
+      while (child_iter->hasNext()) {
+	Instance *child = child_iter->next();
+	makeChildNetwork(child, clone, &bindings, network);
+      }
+      delete child_iter;
+    }
+  }
+}
+
+static void
+makeClonePins(Instance *proto,
+	      Instance *clone,
+	      Instance *clone_view,
+	      ConcreteBindingTbl *bindings,
+	      Instance *parent,
+	      ConcreteBindingTbl *parent_bindings,
+	      NetworkReader *network)
+{
+  InstancePinIterator *proto_pin_iter = network->pinIterator(proto);
+  while (proto_pin_iter->hasNext()) {
+    Pin *proto_pin = proto_pin_iter->next();
+    Net *proto_net = network->net(proto_pin);
+    Port *proto_port = network->port(proto_pin);
+    Net *clone_net = nullptr;
+    if (proto_net && parent_bindings)
+      clone_net = parent_bindings->ensureBinding(proto_net, parent);
+    Pin *clone_pin = network->connect(clone, proto_port, clone_net);
+    if (clone_view) {
+      Pin *clone_proto_pin = network->findPin(clone_view, proto_port);
+      Net *clone_proto_net = network->net(clone_proto_pin);
+      Net *clone_child_net = nullptr;
+      if (clone_proto_net)
+	clone_child_net = bindings->ensureBinding(clone_proto_net, clone);
+      network->makeTerm(clone_pin, clone_child_net);
+    }
+  }
+  delete proto_pin_iter;
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteBindingTbl::ConcreteBindingTbl(NetworkEdit *network) :
+  network_(network)
+{
+}
+
+// Follow the merged_into pointers rather than update the
+// binding tables up the call tree when nodes are merged
+// because the name changes up the hierarchy.
+Net *
+ConcreteBindingTbl::find(Net *proto_net)
+{
+  ConcreteNet *net = reinterpret_cast<ConcreteNet*>(map_.findKey(proto_net));
+  while (net && net->mergedInto())
+    net = net->mergedInto();
+  return reinterpret_cast<Net*>(net);
+}
+
+void
+ConcreteBindingTbl::bind(Net *proto_net,
+			 Net *net)
+{
+  map_[proto_net] = net;
+}
+
+Net *
+ConcreteBindingTbl::ensureBinding(Net *proto_net,
+				  Instance *parent)
+{
+  Net *net = find(proto_net);
+  if (net == nullptr) {
+    net = network_->makeNet(network_->name(proto_net), parent);
+    map_[proto_net] = net;
+  }
+  return net;
+}
+
+} // namespace
diff --git a/hacks/src/OpenSTA/tcl/NetworkEdit.tcl b/hacks/src/OpenSTA/tcl/NetworkEdit.tcl
new file mode 100644
index 0000000..bdd4057
--- /dev/null
+++ b/hacks/src/OpenSTA/tcl/NetworkEdit.tcl
@@ -0,0 +1,262 @@
+# OpenSTA, Static Timing Analyzer
+# Copyright (c) 2021, Parallax Software, Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# Network editing commands.
+
+namespace eval sta {
+
+proc connect_pin { net pin } {
+  set insts_port [parse_connect_pin $pin]
+  if { $insts_port == 0 } {
+    return 0
+  }
+  set net [get_net_warn "net" $net]
+  if { $net == "NULL" } {
+    return 0
+  }
+  lassign $insts_port inst port
+  connect_pin_cmd $inst $port $net
+  return 1
+}
+
+proc parse_connect_pin { arg } {
+  set path_regexp [path_regexp]
+  set insts_port {}
+  if { [is_object $arg] } {
+    set object_type [object_type $arg]
+    if { $object_type == "Pin" } {
+      set pin $arg
+      set inst [$pin instance]
+      set port [$pin port]
+    } elseif { $object_type == "Port" } {
+      # Explicit port arg - convert to pin.
+      set pin [find_pin [get_name $arg]]
+      set inst [$pin instance]
+      set port [$pin port]
+    } else {
+      sta_error 586 "unsupported object type $object_type."
+    }
+  } else {
+    if {[regexp $path_regexp $arg ignore path_name port_name]} {
+      set inst [find_instance $path_name]
+      if { $inst == "NULL" } {
+	return 0
+      }
+    } else {
+      set inst [top_instance]
+      set port_name $arg
+    }
+    set cell [$inst cell]
+    set port [$cell find_port $port_name]
+    if { $port == "NULL" } {
+      return 0
+    }
+    set pin [$inst find_pin $port_name]
+  }
+  
+  # Make sure the pin is not currently connected to a net.
+  if { $pin != "NULL" \
+	 && ![$pin is_hierarchical] \
+	 && [$pin net] != "NULL" } {
+    return 0
+  }
+  return [list $inst $port]
+}
+
+proc connect_pins { net pins } {
+  sta_warn 372 "connect_pins is deprecated.  Use connect_pin."
+  # Visit the pins to make sure command will succeed.
+  set insts_ports [parse_connect_pins $pins]
+  if { $insts_ports == 0 } {
+    return 0
+  }
+  set net [get_net_warn "net" $net]
+  if { $net == "NULL" } {
+    return 0
+  }
+  foreach {inst port} $insts_ports {
+    connect_pin_cmd $inst $port $net
+  }
+  return 1
+}
+
+proc parse_connect_pins { arg } {
+  set path_regexp [path_regexp]
+  set inst_ports {}
+  # Copy backslashes that will be removed by foreach.
+  set arg [string map {\\ \\\\} $arg]
+  foreach obj $arg {
+    set inst_port [parse_connect_pin $obj]
+    if { $inst_port == 0 } {
+      return 0
+    }
+    set inst_ports [concat $inst_ports $inst_port]
+  }
+  return $inst_ports
+}
+
+################################################################
+
+proc delete_instance { instance } {
+  if { [is_object $instance] } {
+    set object_type [object_type $instance]
+    if { $object_type == "Instance" } {
+      set inst $obj
+    } else {
+      sta_error 587 "unsupported object type $object_type."
+    }
+  } else {
+    set inst [find_instance $instance]
+  }
+  if { $inst != "NULL" } {
+    delete_instance_cmd $inst
+  }
+}
+
+################################################################
+
+proc delete_net { net } {
+  if { [is_object $net] } {
+    set object_type [object_type $net]
+    if { $object_type != "Net" } {
+      sta_error 588 "unsupported object type $object_type."
+    }
+  } else {
+    set net [find_net $net]
+  }
+  if { $net != "NULL" } {
+    delete_net_cmd $net
+  }
+}
+
+################################################################
+
+proc disconnect_pin { net pin } {
+  set net [get_net_warn "net" $net]
+  if { $net == "NULL" } {
+    return 0
+  }
+  if { $pin == "-all" } {
+    set iter [$net connected_pin_iterator]
+    while {[$iter has_next]} {
+      set pin [$iter next]
+      disconnect_pin_cmd $pin
+    }
+    $iter finish
+    return 1
+  } else {
+    set pin1 [get_port_pin_warn "pin" $pin]
+    if { $pin1 == "NULL" } {
+      return 0
+    } else {
+      disconnect_pin_cmd $pin1
+      return 1
+    }
+  }
+}
+
+proc disconnect_pins { net pins } {
+  sta_warn 603 "disconnect_pins is deprecated.  Use disconnect_pin."
+  foreach pin $pins {
+    disconnect_pin $net $pins
+  }
+}
+
+################################################################
+
+proc make_instance { inst_path lib_cell } {
+  set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell]
+  if { $lib_cell != "NULL" } {
+    set path_regexp [path_regexp]
+    if {[regexp $path_regexp $inst_path ignore path_name inst_name]} {
+      set parent [find_instance $path_name]
+      if { $parent == "NULL" } {
+	# Parent instance not found.  This could be a typo, but since
+	# SDC does not escape hierarchy dividers it can also be
+	# an escaped name.
+	set inst_name $inst_path
+	set parent [top_instance]
+      }
+    } else {
+      set inst_name $inst_path
+      set parent [top_instance]
+    }
+    return [make_instance_cmd $inst_name $lib_cell $parent]
+  } else {
+    return 0
+  }
+}
+
+################################################################
+
+proc make_net { net_path } {
+  # Copy backslashes that will be removed by foreach.
+  set net_path [string map {\\ \\\\} $net_path]
+  set path_regexp [path_regexp]
+  if {[regexp $path_regexp $net_path ignore path_name net_name]} {
+    set parent [find_instance $path_name]
+    if { $parent == "NULL" } {
+      return 0
+    }
+  } else {
+    set parent [top_instance]
+    set net_name $net_path
+  }
+  return [make_net_cmd $net_name $parent]
+}
+
+################################################################
+
+proc replace_cell { instance lib_cell } {
+  set cell [get_lib_cell_warn "lib_cell" $lib_cell]
+  if { $cell != "NULL" } {
+    set inst [get_instance_error "instance" $instance]
+    set inst_cell [$inst liberty_cell]
+    if { $inst_cell == "NULL" \
+	   || ![equiv_cell_ports $inst_cell $cell] } {
+      return 0
+    }
+    replace_cell_cmd $inst $cell
+    return 1
+  } else {
+    return 0
+  }
+}
+
+proc replace_to_scan_cell { instance } {
+  set inst [get_instance_error "instance" $instance]
+  set inst_cell [get_full_name [$inst liberty_cell]]
+  #Target scan cell __d to __sd
+  #example sky130_fd_sc_hd__dfrtp_2 to sky130_fd_sc_hd__sdfrtp_2
+  set inst_scell [regsub -all "__d" $inst_cell "__sd"]
+  puts "Info: Scan Swapping => Instance:$instance From:$inst_cell to:$inst_scell";
+  if { $inst_cell == "NULL"} {
+    return 0
+  }
+  set scell [get_lib_cell_warn "lib_cell" $inst_scell]
+  replace_cell_cmd $inst $scell
+  return 1
+}
+
+proc path_regexp {} {
+  global hierarchy_separator
+  set id_regexp "\[^${hierarchy_separator}\]+"
+  set prefix_regexp "${id_regexp}(?:${hierarchy_separator}${id_regexp})*"
+  return "^(${prefix_regexp})${hierarchy_separator}(${id_regexp})$"
+}
+
+# sta namespace end.
+}
diff --git a/hacks/src/OpenSTA/tcl/Sta.tcl b/hacks/src/OpenSTA/tcl/Sta.tcl
new file mode 100644
index 0000000..a6e8e34
--- /dev/null
+++ b/hacks/src/OpenSTA/tcl/Sta.tcl
@@ -0,0 +1,1557 @@
+# OpenSTA, Static Timing Analyzer
+# Copyright (c) 2021, Parallax Software, Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+namespace eval sta {
+
+################################################################
+#
+# Non-SDC commands
+#
+################################################################
+
+define_cmd_args "delete_clock" {[-all] clocks}
+
+proc delete_clock { args } {
+  parse_key_args "delete_clock" args keys {} flags {-all}
+  if { [info exists flags(-all)] } {
+    check_argc_eq0 "delete_clock" $args
+    set clks [all_clocks]
+  } else {
+    check_argc_eq1 "delete_clock" $args
+    set clks [get_clocks_warn "clocks" [lindex $args 0]]
+  }
+  foreach clk $clks {
+    remove_clock_cmd $clk
+  }
+}
+
+################################################################
+
+define_cmd_args "delete_generated_clock" {[-all] clocks}
+
+proc delete_generated_clock { args } {
+  remove_gclk_cmd "delete_generated_clock" $args
+}
+
+################################################################
+
+define_cmd_args "set_disable_inferred_clock_gating" { objects }
+
+proc set_disable_inferred_clock_gating { objects } {
+  set_disable_inferred_clock_gating_cmd $objects
+}
+
+proc set_disable_inferred_clock_gating_cmd { objects } {
+  parse_inst_port_pin_arg $objects insts pins
+  foreach inst $insts {
+    disable_clock_gating_check_inst $inst
+  }
+  foreach pin $pins {
+    disable_clock_gating_check_pin $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_case_analysis" {pins}
+
+proc unset_case_analysis { pins } {
+  set pins1 [get_port_pins_error "pins" $pins]
+  foreach pin $pins1 {
+    unset_case_analysis_cmd $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_groups" \
+  {[-logically_exclusive] [-physically_exclusive]\
+     [-asynchronous] [-name names] [-all]}
+				
+proc unset_clock_groups { args } {
+  unset_clk_groups_cmd "unset_clock_groups" $args
+}
+
+proc unset_clk_groups_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-name} \
+    flags {-logically_exclusive -physically_exclusive -asynchronous -all}
+
+  set all [info exists flags(-all)]
+  set names {}
+  if {[info exists keys(-name)]} {
+    set names $keys(-name)
+  }
+
+  if { $all && $names != {} } {
+    sta_error 454 "the -all and -name options are mutually exclusive."
+  }
+  if { !$all && $names == {} } {
+    sta_error 455 "either -all or -name options must be specified."
+  }
+
+  set logically_exclusive [info exists flags(-logically_exclusive)]
+  set physically_exclusive [info exists flags(-physically_exclusive)]
+  set asynchronous [info exists flags(-asynchronous)]
+
+  if { ($logically_exclusive+$physically_exclusive+$asynchronous) == 0 } {
+    sta_error 456 "one of -logically_exclusive, -physically_exclusive or -asynchronous is required."
+  }
+  if { ($logically_exclusive+$physically_exclusive+$asynchronous) > 1 } {
+    sta_error 457 "the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive."
+  }
+
+  if { $all } {
+    if { $logically_exclusive } {
+      unset_clock_groups_logically_exclusive "NULL"
+    } elseif { $physically_exclusive } {
+      unset_clock_groups_physically_exclusive "NULL"
+    } elseif { $asynchronous } {
+      unset_clock_groups_asynchronous "NULL"
+    }
+  } else {
+    foreach name $names {
+      if { $logically_exclusive } {
+	unset_clock_groups_logically_exclusive $name
+      } elseif { $physically_exclusive } {
+	unset_clock_groups_physically_exclusive $name
+      } elseif { $asynchronous } {
+	unset_clock_groups_asynchronous $name
+      }
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects}
+
+proc unset_clock_latency { args } {
+  unset_clk_latency_cmd "unset_clock_latency" $args
+}
+
+proc unset_clk_latency_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {-clock} flags {-source}
+  check_argc_eq1 $cmd $cmd_args
+  set objects [lindex $cmd_args 0]
+  parse_clk_port_pin_arg $objects clks pins
+  set pin_clk "NULL"
+  if { [info exists keys(-clock)] } {
+    set pin_clk [get_clock_warn "clock" $keys(-clock)]
+    if { $clks != {} } {
+      sta_warn 303 "-clock ignored for clock objects."
+    }
+  }
+
+  if {[info exists flags(-source)]} {
+    # Source latency.
+    foreach clk $clks {
+      unset_clock_insertion_cmd $clk "NULL"
+    }
+    foreach pin $pins {
+      # Source only allowed on clocks and clock pins.
+      if { ![is_clock_pin $pin] } {
+	sta_error 458 "-source '[$pin path_name]' is not a clock pin."
+      }
+      unset_clock_insertion_cmd $pin_clk $pin
+    }
+  } else {
+    # Latency.
+    foreach clk $clks {
+      unset_clock_latency_cmd $clk "NULL"
+    }
+    foreach pin $pins {
+      unset_clock_latency_cmd $pin_clk $pin
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_transition" {clocks}
+
+proc unset_clock_transition { args } {
+  check_argc_eq1 "unset_clock_transition" $args
+  set clks [get_clocks_warn "clocks" [lindex $args 0]]
+  foreach clk $clks {
+    unset_clock_slew_cmd $clk
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_uncertainty" \
+  {[-from|-rise_from|-fall_from from_clock]\
+     [-to|-rise_to|-fall_to to_clock] [-rise] [-fall]\
+     [-setup] [-hold] [objects]}
+
+proc unset_clock_uncertainty { args } {
+  unset_clk_uncertainty_cmd "unset_clock_uncertainty" $args
+}
+
+proc unset_clk_uncertainty_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -rise_from -fall_from -to -rise_to -fall_to} \
+    flags {-rise -fall -setup -hold}
+
+  set min_max "min_max"
+  if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
+    set min_max "max"
+  }
+  if { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
+    set min_max "min"
+  }
+
+  if { [info exists keys(-from)] } {
+    set from_key "-from"
+    set from_rf "rise_fall"
+  } elseif { [info exists keys(-rise_from)] } {
+    set from_key "-rise_from"
+    set from_rf "rise"
+  } elseif { [info exists keys(-fall_from)] } {
+    set from_key "-fall_from"
+    set from_rf "fall"
+  } else {
+    set from_key "none"
+  }
+
+  if { [info exists keys(-to)] } {
+    set to_key "-to"
+    set to_rf "rise_fall"
+  } elseif { [info exists keys(-rise_to)] } {
+    set to_key "-rise_to"
+    set to_rf "rise"
+  } elseif { [info exists keys(-fall_to)] } {
+    set to_key "-fall_to"
+    set to_rf "fall"
+  } else {
+    set to_key "none"
+  }
+
+  if { $from_key != "none" && $to_key == "none" \
+	 || $from_key == "none" && $to_key != "none" } {
+    sta_error 459 "-from/-to must be used together."
+  } elseif { $from_key != "none" && $to_key != "none" } {
+    # Inter-clock uncertainty.
+    check_argc_eq0 "unset_clock_uncertainty" $cmd_args
+
+    # -from/-to can be lists.
+    set from_clks [get_clocks_warn "from_clocks" $keys($from_key)]
+    set to_clks [get_clocks_warn "to_clocks" $keys($to_key)]
+
+    foreach from_clk $from_clks {
+      foreach to_clk $to_clks {
+	unset_inter_clock_uncertainty $from_clk $from_rf \
+	  $to_clk $to_rf $min_max
+      }
+    }
+  } else {
+    # Single clock uncertainty.
+    check_argc_eq1 $cmd $cmd_args
+    if { [info exists keys(-rise)] \
+	   || [info exists keys(-fall)] } {
+      sta_error 460 "-rise, -fall options not allowed for single clock uncertainty."
+    }
+    set objects [lindex $cmd_args 0]
+    parse_clk_port_pin_arg $objects clks pins
+
+    foreach clk $clks {
+      unset_clock_uncertainty_clk $clk $min_max
+    }
+    foreach pin $pins {
+      unset_clock_uncertainty_pin $pin $min_max
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_data_check" \
+  {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\
+     [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\
+     [-setup | -hold] [-clock clock]}
+
+proc unset_data_check { args } {
+  unset_data_checks_cmd "unset_data_check" $args
+}
+
+proc unset_data_checks_cmd { cmd cmd_args } {
+  parse_key_args cmd cmd_args \
+    keys {-from -rise_from -fall_from -to -rise_to -fall_to -clock} \
+    flags {-setup -hold}
+  check_argc_eq0 $cmd $cmd_args
+
+  set from_rf "rise_fall"
+  set to_rf "rise_fall"
+  set clk "NULL"
+  set setup_hold "max"
+  if [info exists keys(-from)] {
+    set from [get_port_pin_error "from_pin" $keys(-from)]
+  } elseif [info exists keys(-rise_from)] {
+    set from [get_port_pin_error "from_pin" $keys(-rise_from)]
+    set from_rf "rise"
+  } elseif [info exists keys(-fall_from)] {
+    set from [get_port_pin_error "from_pin" $keys(-fall_from)]
+    set from_rf "fall"
+  } else {
+    sta_error 461 "missing -from, -rise_from or -fall_from argument."
+  }
+
+  if [info exists keys(-to)] {
+    set to [get_port_pin_error "to_pin" $keys(-to)]
+  } elseif [info exists keys(-rise_to)] {
+    set to [get_port_pin_error "to_pin" $keys(-rise_to)]
+    set to_rf "rise"
+  } elseif [info exists keys(-fall_to)] {
+    set to [get_port_pin_error "to_pin" $keys(-fall_to)]
+    set to_rf "fall"
+  } else {
+    sta_error 462 "missing -to, -rise_to or -fall_to argument."
+  }
+
+  if [info exists keys(-clock)] {
+    set clk [get_clock_warn "clock" $keys(-clock)]
+  }
+
+  if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
+    set setup_hold "setup"
+  } elseif { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
+    set setup_hold "hold"
+  } else {
+    set setup_hold "setup_hold"
+  }
+
+  unset_data_check_cmd $from $from_rf $to $to_rf $clk $setup_hold
+}
+
+################################################################
+
+define_cmd_args "unset_disable_inferred_clock_gating" { objects }
+
+proc unset_disable_inferred_clock_gating { objects } {
+  unset_disable_inferred_clock_gating_cmd $objects
+}
+
+proc unset_disable_inferred_clock_gating_cmd { objects } {
+  parse_inst_port_pin_arg $objects insts pins
+  foreach inst $insts {
+    unset_disable_clock_gating_check_inst $inst
+  }
+  foreach pin $pins {
+    unset_disable_clock_gating_check_pin $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_disable_timing" \
+  {[-from from_port] [-to to_port] objects}
+
+proc unset_disable_timing { args } {
+  unset_disable_cmd "unset_disable_timing" $args
+}
+
+proc unset_disable_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {-from -to} flags {}
+  check_argc_eq1 $cmd $cmd_args
+
+  set from ""
+  if { [info exists keys(-from)] } {
+    set from $keys(-from)
+  }
+  set to ""
+  if { [info exists keys(-to)] } {
+    set to $keys(-to)
+  }
+  parse_libcell_libport_inst_port_pin_edge_timing_arc_set_arg $cmd_args \
+    libcells libports insts ports pins edges timing_arc_sets
+
+  if { ([info exists keys(-from)] || [info exists keys(-to)]) \
+	 && ($libports != {} || $pins != {} || $ports != {}) } {
+    sta_warn 304 "-from/-to keywords ignored for lib_pin, port and pin arguments."
+  }
+
+  foreach libcell $libcells {
+    unset_disable_timing_cell $libcell $from $to
+  }
+  foreach libport $libports {
+    unset_disable_lib_port $libport
+  }
+  foreach inst $insts {
+    unset_disable_timing_instance $inst $from $to
+  }
+  foreach pin $pins {
+    unset_disable_pin $pin
+  }
+  foreach port $ports {
+    unset_disable_port $port
+  }
+  foreach edge $edges {
+    unset_disable_edge $edge
+  }
+  foreach timing_arc_set $timing_arc_sets {
+    unset_disable_timing_arc_set $timing_arc_set
+  }
+}
+
+proc unset_disable_timing_cell { cell from to } {
+  set from_ports [parse_disable_cell_ports $cell $from]
+  set to_ports [parse_disable_cell_ports $cell $to]
+  if { $from_ports == "NULL" && $to_ports == "NULL" } {
+    unset_disable_cell $cell "NULL" "NULL"
+  } elseif { $from_ports == "NULL" } {
+    foreach to_port $to_ports {
+      unset_disable_cell $cell "NULL" $to_port
+    }
+  } elseif { $to_ports == "NULL" } {
+    foreach from_port $from_ports {
+      unset_disable_cell $cell $from_port "NULL"
+    }
+  } else {
+    foreach from_port $from_ports {
+      foreach to_port $to_ports {
+	unset_disable_cell $cell $from_port $to_port
+      }
+    }
+  }
+}
+
+proc unset_disable_timing_instance { inst from to } {
+  set from_ports [parse_disable_inst_ports $inst $from]
+  set to_ports [parse_disable_inst_ports $inst $to]
+  if { ![$inst is_leaf] } {
+    sta_error 463 "-from/-to hierarchical instance not supported."
+  }
+  if { $from_ports == "NULL" && $to_ports == "NULL" } {
+    unset_disable_instance $inst "NULL" "NULL"
+  } elseif { $from_ports == "NULL" } {
+    foreach to_port $to_ports {
+      unset_disable_instance $inst "NULL" $to_port
+    }
+  } elseif { $to_ports == "NULL" } {
+    foreach from_port $from_ports {
+      unset_disable_instance $inst $from_port "NULL"
+    }
+  } else {
+    foreach from_port $from_ports {
+      foreach to_port $to_ports {
+	unset_disable_instance $inst $from_port $to_port
+      }
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_generated_clock" {[-all] clocks}
+
+proc unset_generated_clock { args } {
+  unset_gclk_cmd "unset_generated_clock" $args
+}
+
+proc remove_gclk_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {} flags {-all}
+  if { [info exists flags(-all)] } {
+    check_argc_eq0 $cmd $cmd_args
+    set clks [all_clocks]
+  } else {
+    check_argc_eq1 $cmd $cmd_args
+    set clks [get_clocks_warn "clocks" [lindex $cmd_args 0]]
+  }
+  foreach clk $clks {
+    if { [$clk is_generated] } {
+      remove_clock_cmd $clk
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_input_delay" \
+  {[-rise] [-fall] [-max] [-min]\
+     [-clock clock] [-clock_fall]\
+     port_pin_list}
+
+proc unset_input_delay { args } {
+  unset_port_delay "unset_input_delay" "unset_input_delay_cmd" $args
+}
+
+################################################################
+
+define_cmd_args "unset_output_delay" \
+  {[-rise] [-fall] [-max] [-min]\
+     [-clock clock] [-clock_fall]\
+     port_pin_list}
+
+proc unset_output_delay { args } {
+  unset_port_delay "unset_output_delay" "unset_output_delay_cmd" $args
+}
+
+proc unset_port_delay { cmd swig_cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-clock -reference_pin} \
+    flags {-rise -fall -max -min -clock_fall }
+  check_argc_eq1 $cmd $cmd_args
+  
+  set pins [get_port_pins_error "pins" [lindex $cmd_args 0]]
+  
+  set clk "NULL"
+  if [info exists keys(-clock)] {
+    set clk [get_clock_warn "clock" $keys(-clock)]
+  }
+  
+  if [info exists flags(-clock_fall)] {
+    set clk_rf "fall"
+  } else {
+    set clk_rf "rise"
+  }
+  
+  set tr [parse_rise_fall_flags flags]
+  set min_max [parse_min_max_all_flags flags]
+
+  foreach pin $pins {
+    $swig_cmd $pin $tr $clk $clk_rf $min_max
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_path_exceptions" \
+  {[-setup] [-hold] [-rise] [-fall] [-from from_list]\
+     [-rise_from from_list] [-fall_from from_list]\
+     [-through through_list] [-rise_through through_list]\
+     [-fall_through through_list] [-to to_list] [-rise_to to_list]\
+     [-fall_to to_list]}
+
+proc unset_path_exceptions { args } {
+  unset_path_exceptions_cmd "unset_path_exceptions" $args
+}
+
+proc unset_path_exceptions_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -rise_from -fall_from -to -rise_to -fall_to} \
+    flags {-setup -hold -rise -fall} 0
+
+  set min_max "min_max"
+  if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
+    set min_max "max"
+  }
+  if { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
+    set min_max "min"
+  }
+
+  set arg_error 0
+  set from [parse_from_arg keys arg_error]
+  set thrus [parse_thrus_arg cmd_args arg_error]
+  set to [parse_to_arg keys flags arg_error]
+  if { $arg_error } {
+    delete_from_thrus_to $from $thrus $to
+    sta_error 464 "$cmd command failed."
+    return 0
+  }
+
+  check_for_key_args $cmd cmd_args
+  if { $cmd_args != {} } {
+    delete_from_thrus_to $from $thrus $to
+    sta_error 465 "positional arguments not supported."
+  }
+  if { ($from == "NULL" && $thrus == "" && $to == "NULL") } {
+    delete_from_thrus_to $from $thrus $to
+    sta_error 466 "-from, -through or -to required."
+  }
+
+  reset_path_cmd $from $thrus $to $min_max
+  delete_from_thrus_to $from $thrus $to
+}
+
+################################################################
+
+define_cmd_args "unset_propagated_clock" {objects}
+
+proc unset_propagated_clock { objects } {
+  parse_clk_port_pin_arg $objects clks pins
+  foreach clk $clks {
+    unset_propagated_clock_cmd $clk
+  }
+  foreach pin $pins {
+    unset_propagated_clock_pin_cmd $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_timing_derate" {}
+
+proc unset_timing_derate { args } {
+  check_argc_eq0 "unset_timing_derate" $args
+  reset_timing_derate_cmd
+}
+
+################################################################
+#
+# Network editing commands
+#  
+################################################################
+
+define_cmd_args "connect_pin" {net pin}
+# deprecated 2.0.16 05/02/2019
+define_cmd_args "connect_pins" {net pins}
+
+define_cmd_args "delete_instance" {inst}
+
+define_cmd_args "delete_net" {net}
+
+define_cmd_args "disconnect_pin" {net -all|pin}
+# deprecated 2.0.16 05/02/2019
+define_cmd_args "disconnect_pins" {net -all|pins}
+
+define_cmd_args "make_instance" {inst_path lib_cell}
+
+define_cmd_args "make_net" {}
+
+define_cmd_args "replace_cell" {instance lib_cell}
+define_cmd_args "replace_to_scan_cell" {instance}
+
+define_cmd_args "insert_buffer" {buffer_name buffer_cell net load_pins\
+				       buffer_out_net_name}
+
+################################################################
+#
+# Delay calculation commands
+#  
+################################################################
+
+define_cmd_args "set_assigned_delay" \
+  {-cell|-net [-rise] [-fall] [-corner corner_name] [-min] [-max]\
+     [-from from_pins] [-to to_pins] delay}
+
+# Change the delay for timing arcs between from_pins and to_pins matching
+# on cell (instance) or net.
+proc set_assigned_delay { args } {
+  set_assigned_delay_cmd "set_assigned_delay" $args
+}
+
+proc set_assigned_delay_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {-corner -from -to} \
+    flags {-cell -net -rise -fall -max -min}
+  check_argc_eq1 $cmd $cmd_args
+  set corner [parse_corner keys]
+  set min_max [parse_min_max_all_check_flags flags]
+  set to_rf [parse_rise_fall_flags flags]
+
+  if [info exists keys(-from)] {
+    set from_pins [get_port_pins_error "from_pins" $keys(-from)]
+  } else {
+    sta_error 442 "$cmd missing -from argument."
+  }
+  if [info exists keys(-to)] {
+    set to_pins [get_port_pins_error "to_pins" $keys(-to)]
+  } else {
+    sta_error 443 "$cmd missing -to argument."
+  }
+
+  set delay [lindex $cmd_args 0]
+  if {![string is double $delay]} {
+    sta_error 444 "$cmd delay is not a float."
+  }
+  set delay [time_ui_sta $delay]
+
+  if {[info exists flags(-cell)] && [info exists flags(-net)]} {
+    sta_error 445 "set_annotated_delay -cell and -net options are mutually excluive."
+  } elseif {[info exists flags(-cell)]} {
+    if { $from_pins != {} } {
+      set inst [[lindex $from_pins 0] instance]
+      foreach pin $from_pins {
+	if {[$pin instance] != $inst} {
+	  sta_error 446 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]."
+	}
+      }
+      foreach pin $to_pins {
+	if {[$pin instance] != $inst} {
+	  sta_error 447 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]"
+	}
+      }
+    }
+  } elseif {![info exists flags(-net)]} {
+    sta_error 448 "$cmd -cell or -net required."
+  }
+  foreach from_pin $from_pins {
+    set from_vertices [$from_pin vertices]
+    set_assigned_delay1 [lindex $from_vertices 0] \
+      $to_pins $to_rf $corner $min_max $delay
+    if { [llength $from_vertices] == 2 } {
+      set_assigned_delay1 [lindex $from_vertices 1] \
+	$to_pins $to_rf $corner $min_max $delay
+    }
+  }
+}
+
+proc set_assigned_delay1 { from_vertex to_pins to_rf corner min_max delay } {
+  foreach to_pin $to_pins {
+    set to_vertices [$to_pin vertices]
+    set_assigned_delay2 $from_vertex [lindex $to_vertices 0] \
+      $to_rf $corner $min_max $delay
+    if { [llength $to_vertices] == 2 } {
+      # Bidirect driver.
+      set_assigned_delay2 $from_vertex [lindex $to_vertices 1] \
+	$to_rf $corner $min_max $delay
+    }
+  }
+}
+
+proc set_assigned_delay2 {from_vertex to_vertex to_rf corner min_max delay} {
+  set edge_iter [$from_vertex out_edge_iterator]
+  while {[$edge_iter has_next]} {
+    set edge [$edge_iter next]
+    if { [$edge to] == $to_vertex \
+	   && ![timing_role_is_check [$edge role]] } {
+      set arc_iter [$edge timing_arc_iterator]
+      while {[$arc_iter has_next]} {
+	set arc [$arc_iter next]
+	if { $to_rf == "rise_fall" \
+	       || $to_rf eq [$arc to_trans_name] } {
+	  set_arc_delay $edge $arc $corner $min_max $delay
+	}
+      }
+      $arc_iter finish
+    }
+  }
+  $edge_iter finish
+}
+
+################################################################
+
+define_cmd_args "set_assigned_check" \
+  {-setup|-hold|-recovery|-removal [-rise] [-fall]\
+     [-corner corner_name] [-min] [-max]\
+     [-from from_pins] [-to to_pins] [-clock rise|fall]\
+     [-cond sdf_cond] [-worst] check_value}
+
+# -worst is ignored.
+proc set_assigned_check { args } {
+  set_assigned_check_cmd "set_assigned_check" $args
+}
+
+# -worst is ignored.
+proc set_assigned_check_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -to -corner -clock -cond} \
+    flags {-setup -hold -recovery -removal -rise -fall -max -min -worst}
+  check_argc_eq1 $cmd $cmd_args
+
+  if { [info exists keys(-from)] } {
+    set from_pins [get_port_pins_error "from_pins" $keys(-from)]
+  } else {
+    sta_error 449 "$cmd missing -from argument."
+  }
+  set from_rf "rise_fall"
+  if { [info exists keys(-clock)] } {
+    set clk_arg $keys(-clock)
+    if { $clk_arg eq "rise" \
+	   || $clk_arg eq "fall" } {
+      set from_rf $clk_arg
+    } else {
+      sta_error 450 "$cmd -clock must be rise or fall."
+    }
+  }
+
+  if { [info exists keys(-to)] } {
+    set to_pins [get_port_pins_error "to_pins" $keys(-to)]
+  } else {
+    sta_error 451 "$cmd missing -to argument."
+  }
+  set to_rf [parse_rise_fall_flags flags]
+  set corner [parse_corner keys]
+  set min_max [parse_min_max_all_check_flags flags]
+
+  if { [info exists flags(-setup)] } {
+    set role "setup"
+  } elseif { [info exists flags(-hold)] } {
+    set role "hold"
+  } elseif { [info exists flags(-recovery)] } {
+    set role "recovery"
+  } elseif { [info exists flags(-removal)] } {
+    set role "removal"
+  } else {
+    sta_error 452 "$cmd missing -setup|-hold|-recovery|-removal check type.."
+  }
+  set cond ""
+  if { [info exists key(-cond)] } {
+    set cond $key(-cond)
+  }
+  set check_value [lindex $cmd_args 0]
+  if { ![string is double $check_value] } {
+    sta_error 453 "$cmd check_value is not a float."
+  }
+  set check_value [time_ui_sta $check_value]
+
+  foreach from_pin $from_pins {
+    set from_vertices [$from_pin vertices]
+    set_assigned_check1 [lindex $from_vertices 0] $from_rf \
+      $to_pins $to_rf $role $corner $min_max $cond $check_value
+    if { [llength $from_vertices] == 2 } {
+      set_assigned_check1 [lindex $from_vertices 1] $from_rf \
+	$to_pins $to_rf $role $corner $min_max $cond $check_value
+    }
+  }
+}
+
+proc set_assigned_check1 { from_vertex from_rf to_pins to_rf \
+			     role corner min_max cond check_value } {
+  foreach to_pin $to_pins {
+    set to_vertices [$to_pin vertices]
+    set_assigned_check2 $from_vertex $from_rf [lindex $to_vertices 0] \
+      $to_rf $role $corner $min_max $cond $check_value
+    if { [llength $to_vertices] == 2 } {
+      # Bidirect driver.
+      set_assigned_check2 $from_vertex $from_rf \
+	[lindex $to_vertices 1] $to_rf $role $corner $min_max \
+	$cond $check_value
+    }
+  }
+}
+
+proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \
+			     role corner min_max cond check_value } {
+  set edge_iter [$from_vertex out_edge_iterator]
+  while {[$edge_iter has_next]} {
+    set edge [$edge_iter next]
+    if { [$edge to] == $to_vertex } {
+      set arc_iter [$edge timing_arc_iterator]
+      while {[$arc_iter has_next]} {
+	set arc [$arc_iter next]
+	if { ($from_rf eq "rise_fall" \
+		|| $from_rf eq [$arc from_trans_name]) \
+	       && ($to_rf eq "rise_fall" \
+		     || $to_rf eq [$arc to_trans_name]) \
+	       && [$arc role] eq $role \
+	       && ($cond eq "" || [$arc sdf_cond] eq $cond) } {
+	  set_arc_delay $edge $arc $corner $min_max $check_value
+	}
+      }
+      $arc_iter finish
+    }
+  }
+  $edge_iter finish
+}
+
+################################################################a
+
+define_cmd_args "set_assigned_transition" \
+  {[-rise] [-fall] [-corner corner_name] [-min] [-max] slew pins}
+
+# Change the slew on a list of ports.
+proc set_assigned_transition { args } {
+  parse_key_args "set_assigned_transition" args keys {-corner} \
+    flags {-rise -fall -max -min}
+
+  set corner [parse_corner keys]
+  set min_max [parse_min_max_all_check_flags flags]
+  set tr [parse_rise_fall_flags flags]
+  check_argc_eq2 "set_assigned_transition" $args
+
+  set slew [lindex $args 0]
+  if {![string is double $slew]} {
+    sta_error 428 "set_assigned_transition transition is not a float."
+  }
+  set slew [time_ui_sta $slew]
+  set pins [get_port_pins_error "pins" [lindex $args 1]]
+  foreach pin $pins {
+    set vertices [$pin vertices]
+    set vertex [lindex $vertices 0]
+    set_annotated_slew $vertex $corner $min_max $tr $slew
+    if { [llength $vertices] == 2 } {
+      # Bidirect driver.
+      set vertex [lindex $vertices 1]
+      set_annotated_slew $vertex $min_max $tr $slew
+    }
+  }
+}
+
+################################################################a
+
+# compatibility
+define_cmd_args "read_parasitics" \
+  {[-min]\
+     [-max]\
+     [-elmore]\
+     [-path path]\
+     [-increment]\
+     [-pin_cap_included]\
+     [-keep_capacitive_coupling]\
+     [-coupling_reduction_factor factor]\
+     [-reduce_to pi_elmore|pi_pole_residue2]\
+     [-delete_after_reduce]\
+     [-quiet]\
+     [-save]\
+     filename}
+
+################################################################
+#  
+# Utility commands
+#
+################################################################
+
+define_cmd_args "delete_from_list" {list objs}
+
+proc delete_from_list { list objects } {
+  delete_objects_from_list_cmd $list $objects
+}
+
+proc delete_objects_from_list_cmd { list objects } {
+  set list0 [lindex $list 0]
+  set list_is_object [is_object $list0]
+  set list_type [object_type $list0]
+  foreach obj $objects {
+    # If the list is a collection of tcl objects (returned by get_*),
+    # convert the obj to be removed from a name to an object of the same
+    # type.
+    if {$list_is_object && ![is_object $obj]} {
+      if {$list_type == "Clock"} {
+	set obj [find_clock $obj]
+      } elseif {$list_type == "Port"} {
+	set top_instance [top_instance]
+	set top_cell [$top_instance cell]
+	set obj [$top_cell find_port $obj]
+      } elseif {$list_type == "Pin"} {
+	set obj [find_pin $obj]
+      } elseif {$list_type == "Instance"} {
+	set obj [find_instance $obj]
+      } elseif {$list_type == "Net"} {
+	set obj [find_net $obj]
+      } elseif {$list_type == "LibertyLibrary"} {
+	set obj [find_liberty $obj]
+      } elseif {$list_type == "LibertyCell"} {
+	set obj [find_liberty_cell $obj]
+      } elseif {$list_type == "LibertyPort"} {
+	set obj [get_lib_pins $obj]
+      } else {
+	sta_error 439 "unsupported object type $list_type."
+      }
+    }
+    set index [lsearch $list $obj]
+    if { $index != -1 } {
+      set list [lreplace $list $index $index]
+    }
+  }
+  return $list
+}
+
+################################################################
+
+define_cmd_args "get_fanin" \
+  {-to sink_list [-flat] [-only_cells] [-startpoints_only]\
+     [-levels level_count] [-pin_levels pin_count]\
+     [-trace_arcs timing|enabled|all]}
+
+proc get_fanin { args } {
+  parse_key_args "get_fanin" args \
+    keys {-to -levels -pin_levels -trace_arcs} \
+    flags {-flat -only_cells -startpoints_only}
+  if { [llength $args] != 0 } {
+    cmd_usage_error "get_fanin"
+  }
+  if { ![info exists keys(-to)] } {
+    cmd_usage_error "get_fanin"
+  }
+  parse_port_pin_net_arg $keys(-to) pins nets
+  foreach net $nets {
+    lappend pins [net_driver_pins $net]
+  }
+  set flat [info exists flags(-flat)]
+  set only_insts [info exists flags(-only_cells)]
+  set startpoints_only [info exists flags(-startpoints_only)]
+  set inst_levels 0
+  if { [info exists keys(-levels)] } {
+    set inst_levels $keys(-levels)
+  }
+  set pin_levels 0
+  if { [info exists keys(-pin_levels)] } {
+    set pin_levels $keys(-pin_levels)
+  }
+
+  set thru_disabled 0
+  set thru_constants 0
+  if { [info exists keys(-trace_arcs)] } {
+    set trace_arcs $keys(-trace_arcs)
+    if { $trace_arcs == "timing" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "enabled" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "all" } {
+      set thru_disabled 1
+      set thru_constants 1
+    } else {
+      cmd_usage_error "get_fanin"
+    }
+  }
+  if { $only_insts } {
+    return [find_fanin_insts $pins $flat $startpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+ } else {
+    return [find_fanin_pins $pins $flat $startpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+  }
+}
+
+################################################################
+
+define_cmd_args "get_fanout" \
+  {-from source_list [-flat] [-only_cells] [-endpoints_only]\
+     [-levels level_count] [-pin_levels pin_count]\
+     [-trace_arcs timing|enabled|all]}
+
+proc get_fanout { args } {
+  parse_key_args "get_fanout" args \
+    keys {-from -levels -pin_levels -trace_arcs} \
+    flags {-flat -only_cells -endpoints_only}
+  if { [llength $args] != 0 } {
+    cmd_usage_error "get_fanout"
+  }
+  parse_port_pin_net_arg $keys(-from) pins nets
+  foreach net $nets {
+    lappend pins [net_load_pins $net]
+  }
+  set flat [info exists flags(-flat)]
+  set only_insts [info exists flags(-only_cells)]
+  set endpoints_only [info exists flags(-endpoints_only)]
+
+  set inst_levels 0
+  if { [info exists keys(-levels)] } {
+    set inst_levels $keys(-levels)
+  }
+
+  set pin_levels 0
+  if { [info exists keys(-pin_levels)] } {
+    set pin_levels $keys(-pin_levels)
+  }
+
+  set thru_disabled 0
+  set thru_constants 0
+  if { [info exists keys(-trace_arcs)] } {
+    set trace_arcs $keys(-trace_arcs)
+    if { $trace_arcs == "timing" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "enabled" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "all" } {
+      set thru_disabled 1
+      set thru_constants 1
+    } else {
+      cmd_usage_error "get_fanout"
+    }
+  }
+  if { $only_insts } {
+    return [find_fanout_insts $pins $flat $endpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+  } else {
+    return [find_fanout_pins $pins $flat $endpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+  }
+}
+
+################################################################
+
+define_cmd_args "get_name" {objects}
+define_cmd_args "get_full_name" {objects}
+
+################################################################
+
+define_cmd_args "get_property" \
+  {[-object_type cell|pin|net|port|clock|timing_arc] object property}
+
+proc get_property { args } {
+  return [get_property_cmd "get_property" "-object_type" $args]
+}
+
+################################################################
+
+proc get_property_cmd { cmd type_key cmd_args } {
+  parse_key_args $cmd cmd_args keys $type_key flags {-quiet}
+  set quiet [info exists flags(-quiet)]
+  check_argc_eq2 $cmd $cmd_args
+  set object [lindex $cmd_args 0]
+  if { $object == "" } {
+    sta_error 491 "$cmd object is null."
+  } elseif { ![is_object $object] } {
+    if [info exists keys($type_key)] {
+      set object_type $keys($type_key)
+    } else {
+      sta_error 492 "$cmd $type_key must be specified with object name argument."
+    }
+    set object [get_property_object_type $object_type $object $quiet]
+  }
+  set prop [lindex $cmd_args 1]
+  return [get_object_property $object $prop]
+}
+
+proc get_object_property { object prop } {
+  if { [is_object $object] } {
+    set object_type [object_type $object]
+    if { $object_type == "Instance" } {
+      return [instance_property $object $prop]
+    } elseif { $object_type == "Pin" } {
+      return [pin_property $object $prop]
+    } elseif { $object_type == "Net" } {
+      return [net_property $object $prop]
+    } elseif { $object_type == "Clock" } {
+      return [clock_property $object $prop]
+    } elseif { $object_type == "Port" } {
+      return [port_property $object $prop]
+    } elseif { $object_type == "LibertyPort" } {
+      return [liberty_port_property $object $prop]
+    } elseif { $object_type == "LibertyCell" } {
+      return [liberty_cell_property $object $prop]
+    } elseif { $object_type == "Cell" } {
+      return [cell_property $object $prop]
+    } elseif { $object_type == "Library" } {
+      return [library_property $object $prop]
+    } elseif { $object_type == "LibertyLibrary" } {
+      return [liberty_library_property $object $prop]
+    } elseif { $object_type == "Edge" } {
+      return [edge_property $object $prop]
+    } elseif { $object_type == "PathEnd" } {
+      return [path_end_property $object $prop]
+    } elseif { $object_type == "PathRef" } {
+      return [path_ref_property $object $prop]
+    } elseif { $object_type == "TimingArcSet" } {
+      return [timing_arc_set_property $object $prop]
+    } else {
+      sta_error 606 "get_property unsupported object type $object_type."
+    }
+  } else {
+    sta_error 493 "get_property $object is not an object."
+  }
+}
+
+proc get_property_object_type { object_type object_name quiet } {
+  set object "NULL"
+  if { $object_type == "cell" } {
+    set object [get_cells -quiet $object_name]
+  } elseif { $object_type == "pin" } {
+    set object [get_pins -quiet $object_name]
+  } elseif { $object_type == "net" } {
+    set object [get_nets -quiet $object_name]
+  } elseif { $object_type == "port" } {
+    set object [get_ports -quiet $object_name]
+  } elseif { $object_type == "clock" } {
+    set object [get_clocks -quiet $object_name]
+  } elseif { $object_type == "lib_cell" } {
+    set object [get_lib_cells -quiet $object_name]
+  } elseif { $object_type == "lib_pin" } {
+    set object [get_lib_pins -quiet $object_name]
+  } elseif { $object_type == "lib" } {
+    set object [get_libs -quiet $object_name]
+  } else {
+    sta_error 494 "$object_type not supported."
+  }
+  if { $object == "NULL" && !$quiet } {
+    sta_error 495 "$object_type '$object_name' not found."
+  }
+  return [lindex $object 0]
+}
+
+proc get_object_type { obj } {
+  set object_type [object_type $obj]
+  if { $object_type == "Clock" } {
+    return "clock"
+  } elseif { $object_type == "LibertyCell" } {
+    return "libcell"
+  } elseif { $object_type == "LibertyPort" } {
+    return "libpin"
+  } elseif { $object_type == "Cell" } {
+    return "design"
+  } elseif { $object_type == "Instance" } {
+    return "cell"
+  } elseif { $object_type == "Port" } {
+    return "port"
+  } elseif { $object_type == "Pin" } {
+    return "pin"
+  } elseif { $object_type == "Net" } {
+    return "net"
+  } elseif { $object_type == "Edge" } {
+    return "timing_arc"
+  } elseif { $object_type == "TimingArcSet" } {
+    return "timing_arc"
+  } else {
+    return "?"
+  }
+}
+
+proc get_name { object } {
+  return [get_object_property $object "name"]
+}
+
+proc get_full_name { object } {
+  return [get_object_property $object "full_name"]
+}
+
+proc sort_by_name { objects } {
+  return [lsort -command name_cmp $objects]
+}
+
+proc name_cmp { obj1 obj2 } {
+  return [string compare [get_name $obj1] [get_name $obj2]]
+}
+
+proc sort_by_full_name { objects } {
+  return [lsort -command full_name_cmp $objects]
+}
+
+proc full_name_cmp { obj1 obj2 } {
+  return [string compare [get_full_name $obj1] [get_full_name $obj2]]
+}
+
+################################################################
+
+define_cmd_args "get_timing_edges" \
+  {[-from from_pin] [-to to_pin] [-of_objects objects] [-filter expr]}
+
+proc get_timing_edges { args } {
+  return [get_timing_edges_cmd "get_timing_edges" $args]
+}
+
+proc get_timing_edges_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -to -of_objects -filter} flags {}
+  check_argc_eq0 $cmd $cmd_args
+
+  set arcs {}
+  if { [info exists keys(-of_objects)] } {
+    if { [info exists keys(-from)] \
+	   || [info exists keys(-from)] } {
+      sta_error 440 "-from/-to arguments not supported with -of_objects."
+    }
+    set arcs [get_timing_arcs_objects $keys(-of_objects)]
+  } elseif { [info exists keys(-from)] \
+	   && [info exists keys(-to)] } {
+    set arcs [get_timing_arcs_from_to \
+	      [get_port_pin_error "from" $keys(-from)] \
+	      [get_port_pin_error "to" $keys(-to)]]
+  } elseif { [info exists keys(-from)] } {
+    set arcs [get_timing_arcs_from $keys(-from)]
+  } elseif { [info exists keys(-to)] } {
+    set arcs [get_timing_arcs_to $keys(-to)]
+  } else {
+    cmd_usage_error $cmd
+  }
+  if [info exists keys(-filter)] {
+    set arcs [filter_timing_arcs1 $keys(-filter) $arcs]
+  }
+  return $arcs
+}
+
+proc get_timing_arcs_objects { object_arg } {
+  parse_libcell_inst_arg $object_arg libcells insts
+  if { $insts != {} } {
+    set edges {}
+    foreach inst $insts {
+      lappend edges [instance_edges $inst]
+    }
+    return $edges
+  } elseif { $libcells != {} } {
+    set arc_sets {}
+    foreach libcell $libcells {
+      lappend arc_sets [libcell_timing_arc_sets $libcell]
+    }
+    return $arc_sets
+  }
+}
+
+proc instance_edges { inst } {
+  set edges {}
+  set pin_iter [$inst pin_iterator]
+  while {[$pin_iter has_next]} {
+    set pin [$pin_iter next]
+    foreach vertex [$pin vertices] {
+      set edge_iter [$vertex out_edge_iterator]
+      while {[$edge_iter has_next]} {
+	set edge [$edge_iter next]
+	if { [$edge role] != "wire" } {
+	  lappend edges $edge
+	}
+      }
+      $edge_iter finish
+    }
+  }
+  $pin_iter finish
+  return $edges
+}
+
+proc libcell_timing_arc_sets { libcell } {
+  set arc_sets {}
+  set arc_iter [$libcell timing_arc_set_iterator]
+  while { [$arc_iter has_next] } {
+    lappend arc_sets [$arc_iter next]
+  }
+  $arc_iter finish
+  return $arc_sets
+}
+
+proc get_timing_arcs_from_to { from_pin_arg to_pin_arg } {
+  set edges {}
+  set from_pin [get_port_pin_error "from" $from_pin_arg]
+  set to_pin [get_port_pin_error "to" $to_pin_arg]
+  foreach from_vertex [$from_pin vertices] {
+    foreach to_vertex [$to_pin vertices] {
+      set edge_iter [$from_vertex out_edge_iterator]
+      while {[$edge_iter has_next]} {
+	set edge [$edge_iter next]
+	if { [$edge to] == $to_vertex } {
+	  lappend edges $edge
+	}
+      }
+      $edge_iter finish
+    }
+  }
+  return $edges
+}
+
+proc get_timing_arcs_from { from_pin_arg } {
+  set from_pin [get_port_pin_error "from" $from_pin_arg]
+  set edges {}
+  foreach from_vertex [$from_pin vertices] {
+    set edge_iter [$from_vertex out_edge_iterator]
+    while {[$edge_iter has_next]} {
+      set edge [$edge_iter next]
+      lappend edges $edge
+    }
+    $edge_iter finish
+  }
+  return $edges
+}
+
+proc get_timing_arcs_to { to_pin_arg } {
+  set to_pin [get_port_pin_error "to" $to_pin_arg]
+  set edges {}
+  foreach to_vertex [$to_pin vertices] {
+    set edge_iter [$to_vertex in_edge_iterator]
+    while {[$edge_iter has_next]} {
+      set edge [$edge_iter next]
+      lappend edges $edge
+    }
+    $edge_iter finish
+  }
+  return $edges
+}
+
+proc filter_timing_arcs1 { filter objects } {
+  variable filter_regexp1
+  variable filter_or_regexp
+  variable filter_and_regexp
+  set filtered_objects {}
+  # Ignore sub-exprs in filter_regexp1 for expr2 match var.
+  if { [regexp $filter_or_regexp $filter ignore expr1 \
+	  ignore ignore ignore expr2] } {
+    regexp $filter_regexp1 $expr1 ignore attr_name op arg
+    set filtered_objects1 [filter_timing_arcs $attr_name $op $arg $objects]
+    regexp $filter_regexp1 $expr2 ignore attr_name op arg
+    set filtered_objects2 [filter_timing_arcs $attr_name $op $arg $objects]
+    set filtered_objects [concat $filtered_objects1 $filtered_objects2]
+  } elseif { [regexp $filter_and_regexp $filter ignore expr1 \
+		ignore ignore ignore expr2] } {
+    regexp $filter_regexp1 $expr1 ignore attr_name op arg
+    set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
+    regexp $filter_regexp1 $expr2 ignore attr_name op arg
+    set filtered_objects [filter_timing_arcs $attr_name $op \
+			    $arg $filtered_objects]
+  } elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
+    set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
+  } else {
+    sta_error 441 "unsupported -filter expression."
+  }
+  return $filtered_objects
+}
+
+################################################################
+
+define_cmd_args "report_clock_properties" {[clocks]}
+
+proc_redirect report_clock_properties {
+  check_argc_eq0or1 "report_clock_properties" $args
+  update_generated_clks
+  report_line "Clock                   Period          Waveform"
+  report_line "----------------------------------------------------"
+  if { [llength $args] == 0 } {
+    set clk_iter [clock_iterator]
+    while {[$clk_iter has_next]} {
+      set clk [$clk_iter next]
+      report_clock1 $clk
+    }
+    $clk_iter finish
+  } else {
+    foreach clk [get_clocks_warn "clock_name" [lindex $args 0]] {
+      report_clock1 $clk
+    }
+  }
+}
+
+proc report_clock1 { clk } {
+  global sta_report_default_digits
+
+  if { [$clk waveform_valid] } {
+    set digits $sta_report_default_digits
+    set waveform [$clk waveform]
+    if { $waveform == {} } {
+      set wave "                    "
+    } else {
+      set wave ""
+      foreach edge $waveform {
+	set wave "$wave[format "%10s" [format_time $edge $digits]]"
+      }
+    }
+    if {[$clk is_generated]} {
+      set generated " (generated)"
+    } else {
+      set generated ""
+    }
+    report_line "[format %-20s [get_name $clk]][format %10s [format_time [$clk period] $digits]]  $wave$generated"
+  }
+}
+
+################################################################
+
+define_cmd_args "report_object_full_names" {objects}
+
+proc report_object_full_names { objects } {
+  foreach obj [sort_by_full_name $objects] {
+    report_line [get_full_name $obj]
+  }
+}
+
+define_cmd_args "report_object_names" {objects}
+
+proc report_object_names { objects } {
+  foreach obj [sort_by_name $objects] {
+    report_line [get_name $obj]
+  }
+}
+
+################################################################
+
+define_cmd_args "report_units" {}
+
+proc report_units { args } {
+  check_argc_eq0 "report_units" $args
+  foreach unit {"time" "capacitance" "resistance" "voltage" "current" "power" "distance"} {
+    report_line " $unit 1[unit_scale_abreviation $unit][unit_suffix $unit]"
+  }
+}
+
+################################################################
+
+define_cmd_args "with_output_to_variable" { var { cmds }}
+
+# with_output_to_variable variable { command args... }
+proc with_output_to_variable { var_name args } {
+  upvar 1 $var_name var
+
+  set body [lindex $args 0]
+  sta::redirect_string_begin;
+  catch $body ret
+  set var [sta::redirect_string_end]
+  return $ret
+}
+
+define_cmd_args "set_pocv_sigma_factor" { factor }
+
+################################################################
+
+define_cmd_args "write_path_spice" { -path_args path_args\
+				       -spice_directory spice_directory\
+				       -lib_subckt_file lib_subckts_file\
+				       -model_file model_file\
+				       -power power\
+				       -ground ground}
+
+proc write_path_spice { args } {
+  parse_key_args "write_path_spice" args \
+    keys {-spice_directory -lib_subckt_file -model_file \
+	    -power -ground -path_args} \
+    flags {}
+
+  if { [info exists keys(-spice_directory)] } {
+    set spice_dir [file nativename $keys(-spice_directory)]
+    if { ![file exists $spice_dir] } {
+      sta_error 496 "Directory $spice_dir not found."
+    }
+    if { ![file isdirectory $spice_dir] } {
+      sta_error 497 "$spice_dir is not a directory."
+    }
+    if { ![file writable $spice_dir] } {
+      sta_error 498 "Cannot write in $spice_dir."
+    }
+  } else {
+    sta_error 499 "No -spice_directory specified."
+  }
+
+  if { [info exists keys(-lib_subckt_file)] } {
+    set lib_subckt_file [file nativename $keys(-lib_subckt_file)]
+    if { ![file readable $lib_subckt_file] } {
+      sta_error 500 "-lib_subckt_file $lib_subckt_file is not readable."
+    }
+  } else {
+    sta_error 501 "No -lib_subckt_file specified."
+  }
+
+  if { [info exists keys(-model_file)] } {
+    set model_file [file nativename $keys(-model_file)]
+    if { ![file readable $model_file] } {
+      sta_error 502 "-model_file $model_file is not readable."
+    }
+  } else {
+    sta_error 503 "No -model_file specified."
+  }
+
+  if { [info exists keys(-power)] } {
+    set power $keys(-power)
+  } else {
+    sta_error 504 "No -power specified."
+  }
+
+  if { [info exists keys(-ground)] } {
+    set ground $keys(-ground)
+  } else {
+    sta_error 505 "No -ground specified."
+  }
+
+  if { ![info exists keys(-path_args)] } {
+    sta_error 506 "No -path_args specified."
+  }
+  set path_args $keys(-path_args)
+  set path_ends [eval [concat find_timing_paths $path_args]]
+  if { $path_ends == {} } {
+    sta_error 507 "No paths found for -path_args $path_args."
+  } else {
+    set path_index 1
+    foreach path_end $path_ends {
+      set path [$path_end path]
+      set path_name "path_$path_index"
+      set spice_file [file join $spice_dir "$path_name.sp"]
+      set subckt_file [file join $spice_dir "$path_name.subckt"]
+      write_path_spice_cmd $path $spice_file $subckt_file \
+	$lib_subckt_file $model_file $power $ground
+      incr path_index
+    }
+  }
+}
+
+# sta namespace end.
+}
diff --git a/hacks/src/openlane/io_place.py b/hacks/src/openlane/io_place.py
new file mode 100644
index 0000000..f3333f6
--- /dev/null
+++ b/hacks/src/openlane/io_place.py
@@ -0,0 +1,482 @@
+#!/usr/bin/env python3
+# Copyright 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Places the IOs according to an input file. Supports regexes.
+File format:
+#N|#S|#E|#W
+pin1_regex
+pin2_regex
+...
+
+#S|#N|#E|#W
+...
+...
+"""
+
+import os
+import re
+import sys
+import argparse
+import random
+import odb
+
+parser = argparse.ArgumentParser(description='''
+Places the IOs according to an input file. Supports regexes.
+File format:
+#N|#S|#E|#W
+pin1_regex (low co-ordinates to high co-ordinates; e.g., bot to top and left to right)
+pin2_regex
+...
+
+#S|#N|#E|#W
+...
+...
+''')
+
+parser.add_argument('--input-def', '-d', required=True,
+                    help='Input DEF')
+
+parser.add_argument('--input-lef', '-l', required=True,
+                    help='Input LEF')
+
+parser.add_argument('--output-def', '-o',
+                    default='output.def', help='Output DEF with new pin placements')
+
+parser.add_argument('--config', '-cfg',
+                    help='Configuration file. See -h for format')
+
+parser.add_argument('--ver-layer', '-vl',
+                    default=3,
+                    help='Number of metal layer to place the vertical pins on. Defaults to SKY130 metal layer names. 1-based.')
+
+parser.add_argument('--hor-layer', '-hl',
+                    default=4,
+                    help='Number of metal layer to place the horizontal pins on. Defaults to SKY130 metal layer names. 1-based.')
+
+parser.add_argument('--hor-width-mult', '-hwm',
+                    default=2,
+                    help='')
+
+parser.add_argument('--ver-width-mult', '-vwm',
+                    default=2,
+                    help='')
+
+parser.add_argument('--length', '-len', type=float,
+                    default=2,
+                    help='')
+
+parser.add_argument('--hor-extension', '-hext', type=float,
+                    default=0.0,
+                    help='')
+
+parser.add_argument('--ver-extension', '-vext', type=float,
+                    default=0.0,
+                    help='')
+
+parser.add_argument('--reverse', '-rev',
+                    choices=['N', 'E', 'S', 'W'],
+                    nargs='+',
+                    required=False,
+                    default=[],
+                    help='')
+
+parser.add_argument('--bus-sort', '-bsort', action='store_true',
+                    default=False,
+                    help='Sort pins so that bus bits with the same index are grouped'
+                    'together. e.g., a[0] b[0] c[0] a[1] b[1] c[1]')
+# TODO
+# width, length, and extension multipliers
+
+args = parser.parse_args()
+
+def_file_name = args.input_def
+lef_file_name = args.input_lef
+output_def_file_name = args.output_def
+config_file_name = args.config
+bus_sort_flag = args.bus_sort
+
+#Manual Pad Placement - Dinesh A
+manual_place_flag = False 
+
+h_layer_index = int(args.hor_layer)
+v_layer_index = int(args.ver_layer)
+
+h_width_mult = int(args.hor_width_mult)
+v_width_mult = int(args.ver_width_mult)
+
+LENGTH = int(1000*args.length)
+
+H_EXTENSION = int(1000*args.hor_extension)
+V_EXTENSION = int(1000*args.ver_extension)
+
+if H_EXTENSION < 0:
+    H_EXTENSION = 0
+
+if V_EXTENSION < 0:
+    V_EXTENSION = 0
+
+reverse_arr = args.reverse
+reverse_arr = ["#"+rev for rev in reverse_arr]
+
+def getGrid(origin, count, step):
+    tracks = []
+    pos = origin
+    for i in range(count):
+        tracks.append(pos)
+        pos += step
+    assert len(tracks) > 0
+    tracks.sort()
+
+    return tracks
+
+def equallySpacedSeq(m, arr):
+    seq = []
+    n = len(arr)
+    # Bresenham
+    indices = [i*n//m + n//(2*m) for i in range(m)]
+    for i in indices:
+        seq.append(arr[i])
+    return seq
+
+# HUMAN SORTING: https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside
+def atof(text):
+    try:
+        retval = float(text)
+    except ValueError:
+        retval = text
+    return retval
+
+def natural_keys(enum):
+    text = enum[0]
+    text = re.sub("(\[|\]|\.|\$)", "", text)
+    '''
+    alist.sort(key=natural_keys) sorts in human order
+    http://nedbatchelder.com/blog/200712/human_sorting.html
+    (see toothy's implementation in the comments)
+    float regex comes from https://stackoverflow.com/a/12643073/190597
+    '''
+    return [atof(c) for c in re.split(r'[+-]?([0-9]+(?:[.][0-9]*)?|[.][0-9]+)', text)]
+
+def bus_keys(enum):
+    text = enum[0]
+    m = re.match("^.*\[(\d+)\]$", text)
+    if not m:
+        return -1
+    else:
+        return int(m.group(1))
+
+# Find the Slot matching next nearest slot-DineshA
+def findSlot(val, arr):
+    for i in arr:
+        if(i > val):
+            return i
+    print("ERROR: Next Valid Position not found :",val)
+    return -1
+
+
+# read config
+
+pin_placement_cfg = {"#N": [], "#E": [], "#S": [], "#W": []}
+cur_side = None
+if config_file_name is not None and config_file_name != "":
+    with open(config_file_name, 'r') as config_file:
+        for line in config_file:
+            line = line.split()
+            if len(line) == 0:
+                continue
+
+            if(manual_place_flag == False):
+                if len(line) > 1:
+                    print("Only one entry allowed per line.")
+                    sys.exit(1)
+
+                token = line[0]
+            else:
+                #During Manual Place we are allowing Four field
+                # <Pad Name> <Offset> <Position> <Multiplier>
+                # Causion: Make sure that you have given absolute name, else it will give issue
+                if len(line) > 4:
+                    print("Only Four entry allowed per line.")
+                    sys.exit(1)
+                if line[0] not in ["#N", "#E", "#S", "#W", "#NR", "#ER", "#SR", "#WR"]:
+                    token = line
+                else:
+                    token = line[0]
+
+            if cur_side is not None and token[0] != "#":
+                pin_placement_cfg[cur_side].append(token)
+            elif token not in ["#N", "#E", "#S", "#W", "#NR", "#ER", "#SR", "#WR", "#BUS_SORT","#MANUAL_PLACE"]:
+                print("Invalid token: ",token)
+                print("Valid directives are #N, #E, #S, or #W. Append R for reversing the default order.",
+                      "Use #BUS_SORT to group 'bus bits' by index.",
+                      "Use #MANUAL_PLACE Manual Placement <padname> <offset> <pin number>.",
+                      "Please make sure you have set a valid side first before listing pins")
+                sys.exit(1)
+            elif token == "#BUS_SORT":
+                bus_sort_flag = True
+            elif token == "#MANUAL_PLACE":
+                print("Input token ",token)
+                manual_place_flag = True
+            else:
+                if len(token) == 3:
+                    token = token[0:2]
+                    reverse_arr.append(token)
+                cur_side = token
+
+# build a list of pins
+
+db_top = odb.dbDatabase.create()
+odb.read_lef(db_top, lef_file_name)
+odb.read_def(db_top, def_file_name)
+
+chip_top = db_top.getChip()
+block_top = chip_top.getBlock()
+top_design_name = block_top.getName()
+tech = db_top.getTech()
+
+H_LAYER = tech.findRoutingLayer(h_layer_index)
+V_LAYER = tech.findRoutingLayer(v_layer_index)
+
+H_WIDTH = h_width_mult * H_LAYER.getWidth()
+V_WIDTH = v_width_mult * V_LAYER.getWidth()
+
+print("Top-level design name:", top_design_name)
+
+bterms = block_top.getBTerms()
+bterms_enum = []
+for bterm in bterms:
+    pin_name = bterm.getName()
+    bterms_enum.append((pin_name, bterm))
+
+# sort them "humanly"
+bterms_enum.sort(key=natural_keys)
+if bus_sort_flag:
+    bterms_enum.sort(key=bus_keys)
+bterms = [bterm[1] for bterm in bterms_enum]
+
+pin_placement = {"#N": [], "#E": [], "#S": [], "#W": []}
+bterm_regex_map = {}
+if(manual_place_flag == False):
+    for side in pin_placement_cfg:
+        for regex in pin_placement_cfg[side]:  # going through them in order
+            regex += "$"  # anchor
+            for bterm in bterms:
+                # if a pin name matches multiple regexes, their order will be
+                # arbitrary. More refinement requires more strict regexes (or just
+                # the exact pin name).
+                pin_name = bterm.getName()
+                if re.match(regex, pin_name) is not None:
+                    if bterm in bterm_regex_map:
+                        print("Warning: Multiple regexes matched", pin_name,
+                              ". Those are", bterm_regex_map[bterm], "and", regex)
+                        print("Only the first one is taken into consideration.")
+                        continue
+                        # sys.exit(1)
+                    bterm_regex_map[bterm] = regex
+                    pin_placement[side].append(bterm)  # to maintain the order
+    
+    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
+    
+    if len(unmatched_bterms) > 0:
+        print("Warning: Some pins weren't matched by the config file")
+        print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
+        if True:
+            print("Assigning random sides to the above pins")
+            for bterm in unmatched_bterms:
+                random_side = random.choice(list(pin_placement.keys()))
+                pin_placement[random_side].append(bterm)
+        else:
+            sys.exit(1)
+else:
+    for side in pin_placement_cfg:
+        for regex in pin_placement_cfg[side]:  # going through them in order
+            regex = regex[0]  # take first value
+            regex += "$"  # anchor
+            for bterm in bterms:
+                # if a pin name matches multiple regexes, their order will be
+                # arbitrary. More refinement requires more strict regexes (or just
+                # the exact pin name).
+                pin_name = bterm.getName()
+                if re.match(regex, pin_name) is not None:
+                    print("Debug: Serching Pin match",regex)
+                    if bterm in bterm_regex_map:
+                        #print("Warning: Multiple regexes matched", pin_name)
+                        #      ". Those are", bterm_regex_map[bterm], "and", regex)
+                        sys.exit(1)
+                    bterm_regex_map[bterm] = regex
+                    pin_placement[side].append(bterm)  # to maintain the order
+    
+    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
+    
+    if len(unmatched_bterms) > 0:
+        print("Warning: Some pins weren't matched by the config file")
+        print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
+        sys.exit(1)
+
+
+assert len(block_top.getBTerms()) == len(pin_placement["#N"] + pin_placement["#E"] + pin_placement["#S"] + pin_placement["#W"])
+
+# generate slots
+
+
+DIE_AREA = block_top.getDieArea()
+BLOCK_LL_X = DIE_AREA.xMin()
+BLOCK_LL_Y = DIE_AREA.yMin()
+BLOCK_UR_X = DIE_AREA.xMax()
+BLOCK_UR_Y = DIE_AREA.yMax()
+
+print("Block boundaries:", BLOCK_LL_X, BLOCK_LL_Y, BLOCK_UR_X, BLOCK_UR_Y)
+
+
+origin, count, step = block_top.findTrackGrid(H_LAYER).getGridPatternY(0)
+
+# Save the horizontal origin and step - DineshA
+h_origin = origin
+h_step   = step
+
+h_tracks = getGrid(origin, count, step)
+
+origin, count, step = block_top.findTrackGrid(V_LAYER).getGridPatternX(0)
+
+# Save the horizontal origin and step - DineshA
+v_origin = origin
+v_step   = step
+
+v_tracks = getGrid(origin, count, step)
+
+for rev in reverse_arr:
+    pin_placement[rev].reverse()
+
+if(manual_place_flag == False):
+    # create the pins
+    # old logic
+    for side in pin_placement:
+        start = 0
+        if side in ["#N", "#S"]:
+            slots = equallySpacedSeq(len(pin_placement[side]), v_tracks)
+        else:
+            slots = equallySpacedSeq(len(pin_placement[side]), h_tracks)
+    
+        assert len(slots) == len(pin_placement[side])
+    
+        for i in range(len(pin_placement[side])):
+            bterm = pin_placement[side][i]
+            slot = slots[i]
+    
+            pin_name = bterm.getName()
+            pins = bterm.getBPins()
+            if len(pins) > 0:
+                print("Warning:", pin_name, "already has shapes. Modifying them")
+                assert len(pins) == 1
+                pin_bpin = pins[0]
+            else:
+                pin_bpin = odb.dbBPin_create(bterm)
+    
+            print("Dinesh: Placing Pad:" ,pin_name, " At Side: ", side, " Slot: ", slot)
+            pin_bpin.setPlacementStatus("PLACED")
+    
+            if side in ["#N", "#S"]:
+                rect = odb.Rect(0, 0, V_WIDTH, LENGTH+V_EXTENSION)
+                if side == "#N":
+                    y = BLOCK_UR_Y-LENGTH
+                else:
+                    y = BLOCK_LL_Y-V_EXTENSION
+                rect.moveTo(slot-V_WIDTH//2, y)
+                odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
+            else:
+                rect = odb.Rect(0, 0, LENGTH+H_EXTENSION, H_WIDTH)
+                if side == "#E":
+                    x = BLOCK_UR_X-LENGTH
+                else:
+                    x = BLOCK_LL_X-H_EXTENSION
+                rect.moveTo(x, slot-H_WIDTH//2)
+                odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
+else:
+    #New Logic, Manual Pin Placement - Dinesh A
+    #print("Allowed VTracks",v_tracks)
+    #print("Allowed hTracks",h_tracks)
+
+    for side in pin_placement:
+
+        if(len(pin_placement[side]) != len(pin_placement_cfg[side])):
+            print("ERROR : At Side:", side, " Total Pin Defined ",len(pin_placement_cfg[side]), "More than available:",len(pin_placement[side]))
+            
+        #check defined pad are more than avaibale one
+        assert len(pin_placement[side]) == len(pin_placement_cfg[side])
+        start = 0
+    
+        start_loc = 0
+        pad_pos   = 0
+        slot_pre = 0
+        #Dinesh: Give Step Multipler size *2  for better pad placement
+        multiplier= 2
+        for i in range(len(pin_placement_cfg[side])):
+            #Dinesh: Multiply the offset by 1000 for micro conversion
+            if(len(pin_placement_cfg[side][i]) > 1):
+                start_loc = int(pin_placement_cfg[side][i][1])
+            if(len(pin_placement_cfg[side][i]) > 2):
+                pad_pos   = int(pin_placement_cfg[side][i][2])
+            if(len(pin_placement_cfg[side][i]) > 3):
+                multiplier = int(pin_placement_cfg[side][i][3])
+
+            if side in ["#N", "#S"]:
+                slott = start_loc*1000+int(v_origin)+(int(v_step) * pad_pos * multiplier)
+                slot =findSlot(slott,v_tracks)
+            else:
+                slott = start_loc*1000+int(h_origin)+(int(h_step) * pad_pos * multiplier)
+                slot =findSlot(slott,h_tracks)
+          
+            pad_pos +=1
+            bterm = pin_placement[side][i]
+    
+            pin_name = bterm.getName()
+            pins = bterm.getBPins()
+            if len(pins) > 0:
+                print("Warning:", pin_name, "already has shapes. Modifying them")
+                assert len(pins) == 1
+                pin_bpin = pins[0]
+            else:
+                pin_bpin = odb.dbBPin_create(bterm)
+
+            if(slot < slot_pre):
+                print("ERROR:", "Current Pad:", pin_name, " Slot:" , slot, " is less than Previous One:",slot_pre)
+                sys.exit(1)
+
+            slot_pre = slot
+
+            print("Dinesh: Placing Pad:" ,pin_name, " At Side: ", side, " Slot: ", slot)
+            pin_bpin.setPlacementStatus("PLACED")
+    
+            if side in ["#N", "#S"]:
+                rect = odb.Rect(0, 0, V_WIDTH, LENGTH+V_EXTENSION)
+                if side == "#N":
+                    y = BLOCK_UR_Y-LENGTH
+                else:
+                    y = BLOCK_LL_Y-V_EXTENSION
+                rect.moveTo(slot-V_WIDTH//2, y)
+                odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
+            else:
+                rect = odb.Rect(0, 0, LENGTH+H_EXTENSION, H_WIDTH)
+                if side == "#E":
+                    x = BLOCK_UR_X-LENGTH
+                else:
+                    x = BLOCK_LL_X-H_EXTENSION
+                rect.moveTo(x, slot-H_WIDTH//2)
+                odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
+    
+
+print("Writing", output_def_file_name)
+odb.write_def(block_top, output_def_file_name)
diff --git a/hacks/src/openlane/synth.tcl b/hacks/src/openlane/synth.tcl
new file mode 100755
index 0000000..2cf1003
--- /dev/null
+++ b/hacks/src/openlane/synth.tcl
@@ -0,0 +1,373 @@
+# Copyright 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# inputs expected as env vars
+#set opt $::env(SYNTH_OPT)
+set buffering $::env(SYNTH_BUFFERING)
+set sizing $::env(SYNTH_SIZING)
+
+yosys -import
+
+set vtop $::env(DESIGN_NAME)
+#set sdc_file $::env(SDC_FILE)
+set sclib $::env(LIB_SYNTH)
+
+if { [info exists ::env(SYNTH_DEFINES) ] } {
+	foreach define $::env(SYNTH_DEFINES) {
+		log "Defining $define"
+		verilog_defines -D$define
+	}
+}
+
+set vIdirsArgs ""
+if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} {
+	foreach dir $::env(VERILOG_INCLUDE_DIRS) {
+		lappend vIdirsArgs "-I$dir"
+	}
+	set vIdirsArgs [join $vIdirsArgs]
+}
+
+if { $::env(SYNTH_READ_BLACKBOX_LIB) } {
+	log "Reading $::env(LIB_SYNTH_COMPLETE_NO_PG) as a blackbox"
+	foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+	foreach lib $::env(EXTRA_LIBS) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
+	foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
+		read_verilog -sv -lib {*}$vIdirsArgs $verilog_file
+	}
+}
+
+
+# ns expected (in sdc as well)
+set clock_period [expr {$::env(CLOCK_PERIOD)*1000}]
+
+set driver  $::env(SYNTH_DRIVING_CELL)
+set cload   $::env(SYNTH_CAP_LOAD)
+# input pin cap of IN_3VX8
+set max_FO $::env(SYNTH_MAX_FANOUT)
+if {![info exist ::env(SYNTH_MAX_TRAN)]} {
+	set ::env(SYNTH_MAX_TRAN) [expr {0.1*$clock_period}]
+} else {
+	set ::env(SYNTH_MAX_TRAN) [expr {$::env(SYNTH_MAX_TRAN) * 1000}]
+}
+set max_Tran $::env(SYNTH_MAX_TRAN)
+
+
+# Mapping parameters
+set A_factor  0.00
+set B_factor  0.88
+set F_factor  0.00
+
+# Don't change these unless you know what you are doing
+set stat_ext    ".stat.rpt"
+set chk_ext    ".chk.rpt"
+set gl_ext      ".gl.v"
+set constr_ext  ".$clock_period.constr"
+set timing_ext  ".timing.txt"
+set abc_ext     ".abc"
+
+
+# get old sdc, add library specific stuff for abc scripts
+set sdc_file $::env(yosys_tmp_file_tag).sdc
+set outfile [open ${sdc_file} w]
+#puts $outfile $sdc_data
+puts $outfile "set_driving_cell ${driver}"
+puts $outfile "set_load ${cload}"
+close $outfile
+
+
+# ABC Scrips
+set abc_rs_K    "resub,-K,"
+set abc_rs      "resub"
+set abc_rsz     "resub,-z"
+set abc_rw_K    "rewrite,-K,"
+set abc_rw      "rewrite"
+set abc_rwz     "rewrite,-z"
+set abc_rf      "refactor"
+set abc_rfz     "refactor,-z"
+set abc_b       "balance"
+
+set abc_resyn2        "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}"
+set abc_share         "strash; multi,-m; ${abc_resyn2}"
+set abc_resyn2a       "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}"
+set abc_resyn3        "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance"
+set abc_resyn2rs      "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}"
+
+set abc_choice        "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
+set abc_choice2      "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
+
+set abc_map_old_cnt			"map,-p,-a,-B,0.2,-A,0.9,-M,0"
+set abc_map_old_dly         "map,-p,-B,0.2,-A,0.9,-M,0"
+set abc_retime_area         "retime,-D,{D},-M,5"
+set abc_retime_dly          "retime,-D,{D},-M,6"
+set abc_map_new_area        "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
+
+set abc_area_recovery_1       "${abc_choice}; map;"
+set abc_area_recovery_2       "${abc_choice2}; map;"
+
+set map_old_cnt			    "map,-p,-a,-B,0.2,-A,0.9,-M,0"
+set map_old_dly			    "map,-p,-B,0.2,-A,0.9,-M,0"
+set abc_retime_area   	"retime,-D,{D},-M,5"
+set abc_retime_dly    	"retime,-D,{D},-M,6"
+set abc_map_new_area  	"amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
+
+if {$buffering==1} {
+	set abc_fine_tune		"buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}"
+} elseif {$sizing} {
+	set abc_fine_tune       "upsize,{D};dnsize,{D}"
+} else {
+	set abc_fine_tune       ""
+}
+
+
+set delay_scripts [list \
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	\
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	\
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	\
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	]
+
+set area_scripts [list \
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	\
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	\
+	"+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+	]
+
+set all_scripts [list {*}$delay_scripts {*}$area_scripts]
+
+set strategy_parts [split $::env(SYNTH_STRATEGY)]
+
+proc synth_strategy_format_err { } {
+	upvar area_scripts area_scripts
+	upvar delay_scripts delay_scripts
+	log -stderr "\[ERROR] Misformatted SYNTH_STRATEGY (\"$::env(SYNTH_STRATEGY)\")."
+	log -stderr "\[ERROR] Correct format is \"DELAY|AREA 0-[expr [llength $delay_scripts]-1]|0-[expr [llength $area_scripts]-1]\"."
+	exit 1
+}
+
+if { [llength $strategy_parts] != 2 } {
+	synth_strategy_format_err
+}
+
+set strategy_type [lindex $strategy_parts 0]
+set strategy_type_idx [lindex $strategy_parts 1]
+
+if { $strategy_type != "AREA" && $strategy_type != "DELAY" } {
+	log -stderr "\[ERROR] AREA|DELAY tokens not found. ($strategy_type)"
+	synth_strategy_format_err
+}
+
+if { $strategy_type == "DELAY" && $strategy_type_idx >= [llength $delay_scripts] } {
+	log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high."
+	synth_strategy_format_err
+}
+
+if { $strategy_type == "AREA" && $strategy_type_idx >= [llength $area_scripts] } {
+	log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high."
+	synth_strategy_format_err
+}
+
+if { $strategy_type == "DELAY" } {
+	set strategy $strategy_type_idx
+} else {
+	set strategy [expr {[llength $delay_scripts]+$strategy_type_idx}]
+}
+
+set adder_type $::env(SYNTH_ADDER_TYPE)
+if { !($adder_type in [list "YOSYS" "FA" "RCA" "CSA"]) } {
+	log -stderr "\[ERROR] Misformatted SYNTH_ADDER_TYPE (\"$::env(SYNTH_ADDER_TYPE)\")."
+	log -stderr "\[ERROR] Correct format is \"YOSYS|FA|RCA|CSA\"."
+	exit 1
+}
+
+for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } {
+	read_verilog -sv {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i]
+}
+## Module level parameter overide - Dinesh
+if { [info exists ::env(SYNTH_PARAMS) ] } {
+    log "Reading $::env(SYNTH_PARAMS) as a parameter"
+    set records [split $::env(SYNTH_PARAMS) ","]
+    foreach rec $records {
+       chparam -set [lindex $rec 0] [lindex $rec 1] $vtop
+    }
+} else {
+	log "No parameter define found"
+}
+
+select -module $vtop
+
+show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy
+select -clear
+
+hierarchy -check -top $vtop
+
+# Infer tri-state buffers.
+set tbuf_map false
+if { [info exists ::env(TRISTATE_BUFFER_MAP)] } {
+        if { [file exists $::env(TRISTATE_BUFFER_MAP)] } {
+                set tbuf_map true
+                tribuf
+        } else {
+          log "WARNING: TRISTATE_BUFFER_MAP is defined but could not be found: $::env(TRISTATE_BUFFER_MAP)"
+        }
+}
+
+# handle technology mapping of rca and csa adders
+if { $adder_type == "RCA"} {
+	if { [info exists ::env(RIPPLE_CARRY_ADDER_MAP)] && [file exists $::env(RIPPLE_CARRY_ADDER_MAP)] } {
+		techmap -map $::env(RIPPLE_CARRY_ADDER_MAP)
+	}
+} elseif { $adder_type == "CSA"} {
+	if { [info exists ::env(CARRY_SELECT_ADDER_MAP)] && [file exists $::env(CARRY_SELECT_ADDER_MAP)] } {
+		techmap -map $::env(CARRY_SELECT_ADDER_MAP)
+	}
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+	synth -top $vtop
+} else {
+	synth -top $vtop -flatten
+}
+
+# write a post techmap dot file
+show -format dot -prefix $::env(TMP_DIR)/synthesis/post_techmap
+
+if { $::env(SYNTH_SHARE_RESOURCES) } {
+	share -aggressive
+}
+
+set fa_map false
+if { $adder_type == "FA" } {
+	if { [info exists ::env(FULL_ADDER_MAP)] && [file exists $::env(FULL_ADDER_MAP)] } {
+		extract_fa -fa -v
+		extract_fa -ha -v
+		set fa_map true
+	}
+}
+
+opt
+opt_clean -purge
+
+tee -o "$::env(yosys_report_file_tag)_pre.stat" stat
+
+# Map tri-state buffers.
+if { $tbuf_map } {
+        log {mapping tbuf}
+        techmap -map $::env(TRISTATE_BUFFER_MAP)
+        simplemap
+}
+
+# Map Full Adders.
+if { $fa_map } {
+	techmap -map $::env(FULL_ADDER_MAP)
+}
+
+# handle technology mapping of 4-MUX, and tell Yosys to infer 4-muxes
+if { [info exists ::env(SYNTH_MUX4_MAP)] && [file exists $::env(SYNTH_MUX4_MAP)] } {
+  muxcover -mux4 
+  techmap -map $::env(SYNTH_MUX4_MAP)
+  simplemap
+}
+
+# handle technology mapping of 2-MUX
+if { [info exists ::env(SYNTH_MUX_MAP)] && [file exists $::env(SYNTH_MUX_MAP)] } {
+  techmap -map $::env(SYNTH_MUX_MAP)
+  simplemap
+}
+
+# handle technology mapping of latches
+if { [info exists ::env(SYNTH_LATCH_MAP)] && [file exists $::env(SYNTH_LATCH_MAP)] } {
+	techmap -map $::env(SYNTH_LATCH_MAP)
+	simplemap
+}
+
+dfflibmap -liberty $sclib
+tee -o "$::env(yosys_report_file_tag)_dff.stat" stat
+
+if { [info exists ::env(SYNTH_EXPLORE)] && $::env(SYNTH_EXPLORE) } {
+	design -save myDesign
+
+	for { set index 0 }  { $index < [llength $all_scripts] }  { incr index } {
+		log "\[INFO\]: ABC: WireLoad : S_$index"
+		design -load myDesign
+
+		abc -D $clock_period \
+			-constr "$sdc_file" \
+			-liberty $sclib  \
+			-script [lindex $all_scripts $index]
+
+		setundef -zero
+
+		hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT)
+
+		splitnets
+		opt_clean -purge
+		insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+		tee -o "$::env(yosys_report_file_tag)_$index$chk_ext" check
+		tee -o "$::env(yosys_report_file_tag)$index$stat_ext" stat -top $vtop -liberty [lindex $::env(LIB_SYNTH_COMPLETE_NO_PG) 0]
+		write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(yosys_result_file_tag)_$index.v"
+		design -reset
+	}
+} else {
+
+	log "\[INFO\]: ABC: WireLoad : S_$strategy"
+
+	abc -D $clock_period \
+		-constr "$sdc_file" \
+		-liberty $sclib  \
+		-script [lindex $all_scripts $strategy] \
+		-showtmp;
+
+	setundef -zero
+
+	hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT)
+
+	# get rid of the assignments that make init_floorplan fail
+	splitnets
+	opt_clean -purge
+	insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+	tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+	tee -o "$::env(yosys_report_file_tag)_$strategy$stat_ext" stat -top $vtop -liberty [lindex $::env(LIB_SYNTH_COMPLETE_NO_PG) 0]
+	write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+	design -reset
+	read_liberty -lib -ignore_miss_dir -setattr blackbox $::env(LIB_SYNTH_COMPLETE_NO_PG)
+	file copy -force $::env(SAVE_NETLIST) $::env(yosys_tmp_file_tag)_unflat.v
+	read_verilog -sv $::env(SAVE_NETLIST)
+	synth -top $vtop -flatten
+	splitnets
+	opt_clean -purge
+	insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+	write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+	tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+	tee -o "$::env(yosys_report_file_tag)_$strategy$stat_ext" stat -top $vtop -liberty [lindex $::env(LIB_SYNTH_COMPLETE_NO_PG) 0]
+}
diff --git a/hacks/src/openlane/synth_top.tcl b/hacks/src/openlane/synth_top.tcl
new file mode 100755
index 0000000..65bb8fa
--- /dev/null
+++ b/hacks/src/openlane/synth_top.tcl
@@ -0,0 +1,97 @@
+# Copyright 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set vtop $::env(DESIGN_NAME)
+#set sdc_file $::env(SDC_FILE)
+set sclib $::env(LIB_SYNTH)
+yosys -import
+
+set stat_ext    ".stat.rpt"
+set chk_ext    ".chk.rpt"
+set gl_ext      ".gl.v"
+set timing_ext  ".timing.txt"
+set abc_ext     ".abc"
+
+if { $::env(SYNTH_READ_BLACKBOX_LIB) } {
+	foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+	foreach lib $::env(EXTRA_LIBS) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+
+if { [info exists ::env(SYNTH_DEFINES) ] } {
+	foreach define $::env(SYNTH_DEFINES) {
+		verilog_defines -D$define
+	}
+}
+
+set vIdirsArgs ""
+if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} {
+	foreach dir $::env(VERILOG_INCLUDE_DIRS) {
+		lappend vIdirsArgs "-I$dir"
+	}
+	set vIdirsArgs [join $vIdirsArgs]
+}
+
+if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
+	foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
+		read_verilog -lib {*}$vIdirsArgs $verilog_file
+	}
+}
+
+
+for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } {
+  read_verilog {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i]
+}
+
+select -module $vtop
+
+## Module level parameter overide - Dinesh
+if { [info exists ::env(SYNTH_PARAMS) ] } {
+    log "Reading $::env(SYNTH_PARAMS) as a parameter"
+    set records [split $::env(SYNTH_PARAMS) ","]
+    foreach rec $records {
+       chparam -set [lindex $rec 0] [lindex $rec 1] $vtop
+    }
+} else {
+	log "No parameter define found"
+}
+
+
+show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy
+select -clear
+
+hierarchy -check -top $vtop
+if { $::env(SYNTH_FLAT_TOP) } {
+	flatten
+}
+
+setattr -set keep 1
+#synth -top $vtop
+tee -o "$::env(yosys_report_file_tag)_synth.stat" stat
+
+
+#debug opt_clean -purge
+#setundef -zero
+splitnets
+opt_clean -purge
+tee -o "$::env(yosys_report_file_tag)_$chk_ext" check
+tee -o "$::env(yosys_report_file_tag)$stat_ext" stat -top $vtop -liberty $sclib
+write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
diff --git a/openlane/user_project_wrapper/pdn.tcl b/openlane/user_project_wrapper/pdn_cfg.tcl
similarity index 100%
rename from openlane/user_project_wrapper/pdn.tcl
rename to openlane/user_project_wrapper/pdn_cfg.tcl
