#include "Pin.h" #include "Cell.h" #include "DatabaseClass.h" #include "Geometry.h" #include "Layer.h" #include "Net.h" #include "common/utils/utils.h" using namespace db; /***** PinSTA *****/ PinSTA::PinSTA() { type = 'x'; capacitance = -1.0; for (int i = 0; i < 4; i++) { aat[i] = 0.0; rat[i] = 0.0; slack[i] = 0.0; nCriticalPaths[i] = 0; } } /***** IOPin *****/ IOPin::IOPin(const string& name, const string& netName, const char direction) : _netName(netName), name(name) { type = new PinType(name, direction, 's'); pin = new Pin(this); } IOPin::~IOPin() { delete pin; delete type; } void IOPin::getBounds(int& lx, int& ly, int& hx, int& hy, int& rIndex) const { type->getBounds(lx, ly, hx, hy); lx += x; ly += y; hx += x; hy += y; if (type->shapes.size()) { rIndex = type->shapes[0].layer.rIndex; } else { rIndex = -1; } } /***** Pin *****/ Pin::Pin(const PinType* type) : type(type) {} Pin::Pin(Cell* cell, int i) : cell(cell), type(cell->ctype()->pins[i]), parentCellPinId(i) {} Pin::Pin(IOPin* iopin) : iopin(iopin), type(iopin->type) {} Pin::Pin(const Pin& pin) : cell(pin.cell), net(pin.net), type(pin.type) {} void Pin::getPinCenter(int& x, int& y) { int lx, ly, hx, hy; type->getBounds(lx, ly, hx, hy); if (cell) { x = cell->lx() + (lx + hx) / 2; y = cell->ly() + (ly + hy) / 2; } else if (iopin) { x = iopin->x + (lx + hx) / 2; y = iopin->y + (ly + hy) / 2; } else { logger.error("invalid pin %s:%d", __FILE__, __LINE__); x = INT_MIN; y = INT_MIN; } } void Pin::getPinBounds(int& lx, int& ly, int& hx, int& hy, int& rIndex) { if (cell) { type->getBounds(lx, ly, hx, hy); lx += cell->lx(); ly += cell->ly(); hx += cell->lx(); hy += cell->ly(); rIndex = type->shapes[0].layer.rIndex; } else if (iopin) { iopin->getBounds(lx, ly, hx, hy, rIndex); } else { lx = INT_MAX; ly = INT_MAX; hx = INT_MIN; hy = INT_MIN; rIndex = -1; } } utils::BoxT Pin::getPinParentBBox() const { double x, y, w, h; if (this->cell != nullptr) { // cell pin x = this->cell->lx(); y = this->cell->ly(); w = this->cell->width(); h = this->cell->height(); } else { // iopin x = this->iopin->lx(); y = this->iopin->ly(); w = this->iopin->width(); h = this->iopin->height(); } return utils::BoxT(x, y, x + w, y + h); } utils::PointT Pin::getPinParentCenter() const { int cx, cy; if (this->cell != nullptr) { // cell pin cx = this->cell->cx(); cy = this->cell->cy(); } else { // iopin cx = this->iopin->cx(); cy = this->iopin->cy(); } return utils::PointT(cx, cy); } /***** Pin Type *****/ void PinType::addShape(const Layer& layer, const int lx, const int ly, const int hx, const int hy) { boundLX = std::min(boundLX, lx); boundLY = std::min(boundLY, ly); boundHX = std::max(boundHX, hx); boundHY = std::max(boundHY, hy); shapes.emplace_back(layer, lx, ly, hx, hy); } void PinType::getBounds(int& lx, int& ly, int& hx, int& hy) const { lx = boundLX; ly = boundLY; hx = boundHX; hy = boundHY; } bool PinType::operator<(const PinType& r) const { if (boundLX < r.boundLX) { return true; } if (boundLX > r.boundLX) { return false; } if (boundLY < r.boundLY) { return true; } if (boundLY > r.boundLY) { return false; } if (boundHX < r.boundHX) { return true; } if (boundHX > r.boundHX) { return false; } if (boundHY < r.boundHY) { return true; } else if (boundHY == r.boundHY) { if (shapes[0].layer.rIndex < r.shapes[0].layer.rIndex) { return true; } else { return false; } } else { return false; } } bool PinType::comparePin(vector pins1, vector pins2) { std::sort(pins1.begin(), pins1.end(), [](PinType* lhs, PinType* rhs) { return (*lhs < *rhs); }); std::sort(pins2.begin(), pins2.end(), [](PinType* lhs, PinType* rhs) { return (*lhs < *rhs); }); for (unsigned j = 0; j != pins1.size(); ++j) { if (pins1[j]->_type != 'p' && pins1[j]->_type != 'g' && *pins1[j] != *pins2[j]) { return false; } } return true; } bool PinType::operator==(const PinType& r) const { return _type == r._type && boundLX == r.boundLX && boundLY == r.boundLY && boundHX == r.boundHX && boundHY == r.boundHY && shapes[0].layer.rIndex == r.shapes[0].layer.rIndex; }