diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 20a0359f..98a03814 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/include/sta/ConcreteNetwork.hh b/include/sta/ConcreteNetwork.hh index 7bd9014a..1375c58f 100644 --- a/include/sta/ConcreteNetwork.hh +++ b/include/sta/ConcreteNetwork.hh @@ -44,6 +44,7 @@ typedef Map ConcreteInstanceChildMap; typedef Map ConcreteInstanceNetMap; typedef Vector ConcreteNetSeq; +typedef Vector ConcretePinSeq; typedef Map CellNetworkViewMap; typedef Set ConcreteNetSet; @@ -306,7 +307,7 @@ protected: ConcreteCell *cell_; ConcreteInstance *parent_; // Array of pins indexed by pin->port->index(). - ConcretePin **pins_; + ConcretePinSeq pins_; ConcreteInstanceChildMap *children_; ConcreteInstanceNetMap *nets_; diff --git a/include/sta/PortDirection.hh b/include/sta/PortDirection.hh index 4e3b0627..ad2e081f 100644 --- a/include/sta/PortDirection.hh +++ b/include/sta/PortDirection.hh @@ -34,6 +34,7 @@ public: static PortDirection *ground() { return ground_; } static PortDirection *power() { return power_; } static PortDirection *unknown() { return unknown_; } + static PortDirection *find(const char *dir_name); const char *name() const { return name_; } int index() const { return index_; } bool isInput() const { return this == input_; } diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 0fdccfb9..d2c87c93 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1179,6 +1179,8 @@ public: Net *net); // disconnect_net virtual void disconnectPin(Pin *pin); + virtual void makePortPin(const char *port_name, + const char *direction); // Notify STA of network change. void networkChanged(); void deleteLeafInstanceBefore(const Instance *inst); @@ -1196,6 +1198,7 @@ public: virtual void replaceCellBefore(const Instance *inst, const LibertyCell *to_cell); virtual void replaceCellAfter(const Instance *inst); + virtual void makePortPinAfter(Pin *pin); virtual void connectPinAfter(const Pin *pin); virtual void disconnectPinBefore(const Pin *pin); virtual void deleteNetBefore(const Net *net); diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index 12668e87..18e2df18 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -138,7 +138,7 @@ public: private: void findNext(); - ConcretePin **pins_; + const ConcretePinSeq &pins_; int pin_count_; int pin_index_; ConcretePin *next_; @@ -1211,8 +1211,8 @@ ConcreteNetwork::replaceCell(Instance *inst, ConcreteCell *ccell = reinterpret_cast(cell); int port_count = ccell->portBitCount(); ConcreteInstance *cinst = reinterpret_cast(inst); - ConcretePin **pins = cinst->pins_; - ConcretePin **rpins = new ConcretePin*[port_count]; + ConcretePinSeq &pins = cinst->pins_; + ConcretePinSeq rpins(port_count); for (int i = 0; i < port_count; i++) rpins[i] = nullptr; for (int i = 0; i < port_count; i++) { @@ -1227,7 +1227,6 @@ ConcreteNetwork::replaceCell(Instance *inst, } } } - delete [] pins; cinst->pins_ = rpins; cinst->setCell(ccell); } @@ -1333,7 +1332,8 @@ ConcreteNetwork::connect(Instance *inst, if (inst == top_instance_) { // makeTerm ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet); - cnet->addTerm(cterm); + if (cnet) + cnet->addTerm(cterm); cpin->term_ = cterm; cpin->net_ = nullptr; } @@ -1541,20 +1541,13 @@ ConcreteInstance::ConcreteInstance(const char *name, void ConcreteInstance::initPins() { - int pin_count = reinterpret_cast(cell_)->portBitCount(); - if (pin_count) { - pins_ = new ConcretePin*[pin_count]; - for (int i = 0; i < pin_count; i++) - pins_[i] = nullptr; - } - else - pins_ = nullptr; + ConcreteCell *ccell = reinterpret_cast(cell_); + pins_.resize(ccell->portBitCount()); } ConcreteInstance::~ConcreteInstance() { stringDelete(name_); - delete [] pins_; delete children_; delete nets_; } @@ -1585,7 +1578,11 @@ ConcretePin * ConcreteInstance::findPin(const Port *port) const { const ConcretePort *cport = reinterpret_cast(port); - return pins_[cport->pinIndex()]; + size_t port_index = cport->pinIndex(); + if (port_index < pins_.size()) + return pins_[port_index]; + else + return nullptr; } ConcreteNet * @@ -1655,7 +1652,10 @@ void ConcreteInstance::addPin(ConcretePin *pin) { ConcretePort *cport = reinterpret_cast(pin->port()); - pins_[cport->pinIndex()] = pin; + size_t pin_index = cport->pinIndex(); + if (pin_index >= pins_.size()) + pins_.resize(pin_index + 1); + pins_[pin_index] = pin; } void diff --git a/network/PortDirection.cc b/network/PortDirection.cc index a36631c7..cc504cd2 100644 --- a/network/PortDirection.cc +++ b/network/PortDirection.cc @@ -16,6 +16,8 @@ #include "PortDirection.hh" +#include "StringUtil.hh" + namespace sta { PortDirection *PortDirection::input_; @@ -68,6 +70,27 @@ PortDirection::PortDirection(const char *name, { } +PortDirection * +PortDirection::find(const char *dir_name) +{ + if (stringEqual(dir_name, "input")) + return input_; + else if (stringEqual(dir_name, "output")) + return output_; + else if (stringEqual(dir_name, "tristate")) + return tristate_; + else if (stringEqual(dir_name, "bidirect")) + return bidirect_; + else if (stringEqual(dir_name, "internal")) + return internal_; + else if (stringEqual(dir_name, "ground")) + return ground_; + else if (stringEqual(dir_name, "power")) + return power_; + else + return nullptr; +} + bool PortDirection::isAnyInput() const { diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index adf86689..949b5c2d 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -4170,7 +4170,9 @@ Sdc::addException(ExceptionPath *exception) ExceptionFrom *from = exception->from(); if (from && (from->hasPins() || from->hasInstances()) - && from->hasClocks()) { + && from->hasClocks() + // There is only one filter so there are no competing priorities. + && !exception->isFilter()) { PinSet *pins1 = from->pins() ? new PinSet(*from->pins()) : nullptr; InstanceSet *insts1 = from->instances() ? new InstanceSet(*from->instances()) : nullptr; diff --git a/search/Sta.cc b/search/Sta.cc index 103055ea..59484526 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4133,6 +4133,21 @@ Sta::disconnectPin(Pin *pin) network->disconnectPin(pin); } +void +Sta::makePortPin(const char *port_name, + const char *direction) +{ + NetworkReader *network = dynamic_cast(network_); + Instance *top_inst = network->topInstance(); + Cell *top_cell = network->cell(top_inst); + Port *port = network->makePort(top_cell, port_name); + PortDirection *dir = PortDirection::find(direction); + if (dir) + network->setDirection(port, dir); + Pin *pin = network->makePin(top_inst, port, nullptr); + makePortPinAfter(pin); +} + //////////////////////////////////////////////////////////////// // // Network edit before/after methods. @@ -4161,6 +4176,15 @@ Sta::makeInstanceAfter(const Instance *inst) } } +void +Sta::makePortPinAfter(Pin *pin) +{ + if (graph_) { + Vertex *vertex, *bidir_drvr_vertex; + graph_->makePinVertices(pin, vertex, bidir_drvr_vertex); + } +} + void Sta::replaceEquivCellBefore(const Instance *inst, const LibertyCell *to_cell) diff --git a/tcl/NetworkEdit.i b/tcl/NetworkEdit.i index 67a08ecd..0892ba71 100644 --- a/tcl/NetworkEdit.i +++ b/tcl/NetworkEdit.i @@ -73,6 +73,13 @@ make_net_cmd(const char *name, return net; } +void +make_port_pin_cmd(const char *port_name, + const char *direction) +{ + Sta::sta()->makePortPin(port_name, direction); +} + void delete_net_cmd(Net *net) { diff --git a/tcl/NetworkEdit.tcl b/tcl/NetworkEdit.tcl index 1cda520d..639ea95f 100644 --- a/tcl/NetworkEdit.tcl +++ b/tcl/NetworkEdit.tcl @@ -45,7 +45,7 @@ proc make_instance { inst_path lib_cell } { ################################################################ -define_cmd_args "make_net" {} +define_cmd_args "make_net" {net_path} proc make_net { net_path } { # Copy backslashes that will be removed by foreach. @@ -65,6 +65,14 @@ proc make_net { net_path } { ################################################################ +define_cmd_args "make_port" {port_name direction} + +proc make_port { port_name direction } { + make_port_pin_cmd $port_name $direction +} + +################################################################ + define_cmd_args "connect_pin" {net pin} proc connect_pin { net pin } {