2024-11-23 13:09:12 +08:00
|
|
|
#include "Pin.h"
|
|
|
|
|
|
|
|
|
|
#include "Cell.h"
|
|
|
|
|
#include "DatabaseClass.h"
|
|
|
|
|
#include "Geometry.h"
|
|
|
|
|
#include "Layer.h"
|
|
|
|
|
#include "Net.h"
|
|
|
|
|
#include "common/utils/utils.h"
|
|
|
|
|
|
2022-10-20 22:46:17 +08:00
|
|
|
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 *****/
|
|
|
|
|
|
2024-11-23 13:09:12 +08:00
|
|
|
Pin::Pin(const PinType* type) : type(type) {}
|
2025-05-02 13:21:19 +08:00
|
|
|
Pin::Pin(Cell* cell, int i) : cell(cell), type(cell->ctype()->pins[i]), parentCellPinId(i) {
|
|
|
|
|
name = cell->name() + ":" + type->name();
|
|
|
|
|
}
|
2024-11-23 13:09:12 +08:00
|
|
|
Pin::Pin(IOPin* iopin) : iopin(iopin), type(iopin->type) {}
|
|
|
|
|
Pin::Pin(const Pin& pin) : cell(pin.cell), net(pin.net), type(pin.type) {}
|
|
|
|
|
|
2022-10-20 22:46:17 +08:00
|
|
|
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 {
|
2023-04-06 13:34:26 +08:00
|
|
|
logger.error("invalid pin %s:%d", __FILE__, __LINE__);
|
2022-10-20 22:46:17 +08:00
|
|
|
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<double> 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<double>(x, y, x + w, y + h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
utils::PointT<int> 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<int>(cx, cy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Pin Type *****/
|
|
|
|
|
|
|
|
|
|
void PinType::addShape(const Layer& layer, const int lx, const int ly, const int hx, const int hy) {
|
2024-06-05 16:11:25 +08:00
|
|
|
boundLX = std::min(boundLX, lx);
|
|
|
|
|
boundLY = std::min(boundLY, ly);
|
|
|
|
|
boundHX = std::max(boundHX, hx);
|
|
|
|
|
boundHY = std::max(boundHY, hy);
|
2022-10-20 22:46:17 +08:00
|
|
|
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<PinType*> pins1, vector<PinType*> 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;
|
|
|
|
|
}
|
2024-11-23 13:09:12 +08:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|