Added management for "phlib" I/O pad external connectors (for cougar/lvx).
* New: In CRL::ApDriver::DumpSegments(), drive as top-level segments the RoutingPads using a Pin, and not only using a segment. They are not exported as top level Pin but only as Segment as they do belong to a deeper level. * New: In Cumulus/plugins/PadsCorona.Side._placePads(), now manage both "pxlib" and "phlib*". Pad library management is still hardcoded, this should be made a configuration option someday.
This commit is contained in:
parent
02b30b6681
commit
5914e16f26
|
@ -186,6 +186,7 @@ void DumpReference(ofstream& ccell, Cell *cell)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DumpContacts(ofstream& ccell, Cell *cell)
|
||||
{
|
||||
const char* mbkLayer;
|
||||
|
@ -232,11 +233,11 @@ void DumpContacts(ofstream& ccell, Cell *cell)
|
|||
|
||||
void DumpSegments ( ofstream& ccell, Cell* cell )
|
||||
{
|
||||
const char* mbkLayer;
|
||||
const char* mbkLayer = NULL;
|
||||
DbU::Unit x1, x2, y1, y2, width;
|
||||
Segment* segment;
|
||||
RoutingPad* rp;
|
||||
bool external;
|
||||
Segment* segment = NULL;
|
||||
RoutingPad* rp = NULL;
|
||||
bool external = false;
|
||||
|
||||
for ( Net* net : cell->getNets() ) {
|
||||
string netName = toMBKName( net->getName() );
|
||||
|
@ -244,18 +245,38 @@ void DumpContacts(ofstream& ccell, Cell *cell)
|
|||
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if ( (rp = dynamic_cast<RoutingPad*>(component)) ) {
|
||||
if ( not net->isExternal() ) continue;
|
||||
if ( not cell->isRouted() ) continue;
|
||||
if (not net->isExternal()) continue;
|
||||
if (not cell->isRouted()) continue;
|
||||
|
||||
external = true;
|
||||
segment = dynamic_cast<Segment*>(rp->getOccurrence().getEntity());
|
||||
if ( !segment ) continue;
|
||||
|
||||
x1 = rp->getSourceX();
|
||||
x2 = rp->getTargetX();
|
||||
y1 = rp->getSourceY();
|
||||
y2 = rp->getTargetY();
|
||||
width = segment->getWidth();
|
||||
if (segment) {
|
||||
x1 = rp->getSourceX();
|
||||
x2 = rp->getTargetX();
|
||||
y1 = rp->getSourceY();
|
||||
y2 = rp->getTargetY();
|
||||
width = segment->getWidth();
|
||||
} else {
|
||||
Pin* pin = dynamic_cast<Pin*>(rp->getOccurrence().getEntity());
|
||||
if (pin) {
|
||||
Box bb ( pin->getBoundingBox() );
|
||||
rp->getOccurrence().getPath().getTransformation().applyOn( bb );
|
||||
if (bb.getWidth() > bb.getHeight()) {
|
||||
x1 = bb.getCenter().getX();
|
||||
x2 = x1;
|
||||
y1 = bb.getYMin();
|
||||
y2 = bb.getYMax();
|
||||
width = bb.getWidth();
|
||||
} else {
|
||||
x1 = bb.getXMin();
|
||||
x2 = bb.getXMax();
|
||||
y1 = bb.getCenter().getY();
|
||||
y2 = y1;
|
||||
width = bb.getHeight();
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
} else if ( (segment = dynamic_cast<Segment*>(component)) ) {
|
||||
external = NetExternalComponents::isExternal(component);
|
||||
x1 = segment->getSourceX();
|
||||
|
@ -303,93 +324,68 @@ unsigned getPinIndex(Name& pinname)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DumpPins(ofstream &ccell, Cell* cell)
|
||||
{
|
||||
const char* mbkLayer;
|
||||
const char* mbkLayer = NULL;
|
||||
|
||||
for_each_net(net, cell->getExternalNets())
|
||||
{
|
||||
typedef vector<Pin*> PinVector;
|
||||
PinVector pinVector;
|
||||
for_each_pin(pin, net->getPins())
|
||||
{
|
||||
pinVector.push_back(pin);
|
||||
end_for;
|
||||
}
|
||||
sort (pinVector.begin(), pinVector.end(), PinSort());
|
||||
set<unsigned> indexesSet;
|
||||
for (PinVector::const_iterator pvit = pinVector.begin();
|
||||
pvit != pinVector.end();
|
||||
pvit++)
|
||||
{
|
||||
if ( !toMBKLayer(mbkLayer,(*pvit)->getLayer()->getName(),false) ) continue;
|
||||
|
||||
Pin* pin = *pvit;
|
||||
Name pinName(pin->getName());
|
||||
unsigned index = getPinIndex(pinName);
|
||||
if (pinName != net->getName())
|
||||
{
|
||||
throw Error("Pin name (" + getString(pinName)
|
||||
+ ") must look like "
|
||||
+ getString(net->getName())
|
||||
+ "[.index] to be driven in AP format");
|
||||
}
|
||||
if (indexesSet.find(index) != indexesSet.end())
|
||||
{
|
||||
throw Error("Two pins on same net with same index for net : "
|
||||
+ getString(net->getName()));
|
||||
}
|
||||
indexesSet.insert(index);
|
||||
// if (pin->getWidth() != pin->getHeight())
|
||||
// cerr << Warning( "CRL::ApDriver(): Pin \"" + getString(pin->getName()) + "\" of \""
|
||||
// + getString(net->getName())
|
||||
// + "\", AP format support only square shapes.")
|
||||
// << endl;;
|
||||
|
||||
DbU::Unit width = 0;
|
||||
switch ( pin->getAccessDirection() ) {
|
||||
case Pin::AccessDirection::NORTH:
|
||||
case Pin::AccessDirection::SOUTH: width = pin->getWidth(); break;
|
||||
case Pin::AccessDirection::EAST:
|
||||
case Pin::AccessDirection::WEST: width = pin->getHeight(); break;
|
||||
default:
|
||||
cerr << Warning( "CRL::ApDriver(): Pin \"" + getString(pin->getName()) + "\" of \""
|
||||
+ getString(net->getName())
|
||||
+ "\", has undefined access direction.")
|
||||
<< endl;;
|
||||
break;
|
||||
}
|
||||
|
||||
ccell << "C " << toMBKlambda(pin->getX())
|
||||
<< "," << toMBKlambda(pin->getY())
|
||||
<< "," << toMBKlambda(width)
|
||||
<< "," << toMBKName(pinName)
|
||||
<< "," << index
|
||||
<< ",";
|
||||
switch (pin->getAccessDirection())
|
||||
{
|
||||
case Pin::AccessDirection::NORTH:
|
||||
ccell << "NORTH";
|
||||
break;
|
||||
case Pin::AccessDirection::SOUTH:
|
||||
ccell << "SOUTH";
|
||||
break;
|
||||
case Pin::AccessDirection::EAST:
|
||||
ccell << "EAST";
|
||||
break;
|
||||
case Pin::AccessDirection::WEST:
|
||||
ccell << "WEST";
|
||||
break;
|
||||
case Pin::AccessDirection::UNDEFINED:
|
||||
default:
|
||||
throw Error("Pins must a have direction to generate a .ap");
|
||||
}
|
||||
ccell << "," << mbkLayer << endl;
|
||||
}
|
||||
end_for;
|
||||
for ( Net* net : cell->getExternalNets() ) {
|
||||
vector<Pin*> pins;
|
||||
for ( Pin* pin : net->getPins() ) {
|
||||
pins.push_back(pin);
|
||||
}
|
||||
|
||||
sort( pins.begin(), pins.end(), PinSort() );
|
||||
set<unsigned> indexesSet;
|
||||
for ( Pin* pin : pins ) {
|
||||
if (not toMBKLayer(mbkLayer,pin->getLayer()->getName(),false)) continue;
|
||||
|
||||
Name pinName (pin->getName());
|
||||
unsigned index = getPinIndex(pinName);
|
||||
if (pinName != net->getName()) {
|
||||
throw Error( "CRL::ApDriver(): Pin \"%s\" and Net \"%s[.index]\" must have the same name to driven in AP format."
|
||||
, getString(pinName).c_str()
|
||||
, getString(net->getName()).c_str() );
|
||||
}
|
||||
|
||||
if (indexesSet.find(index) != indexesSet.end())
|
||||
throw Error( "CRL::ApDriver(): Net \"%s\" has more than one Pin indexed %u."
|
||||
, getString(net->getName()).c_str(), index );
|
||||
|
||||
indexesSet.insert(index);
|
||||
|
||||
DbU::Unit width = 0;
|
||||
switch ( pin->getAccessDirection() ) {
|
||||
case Pin::AccessDirection::NORTH:
|
||||
case Pin::AccessDirection::SOUTH: width = pin->getWidth(); break;
|
||||
case Pin::AccessDirection::EAST:
|
||||
case Pin::AccessDirection::WEST: width = pin->getHeight(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ccell << "C " << toMBKlambda(pin->getX())
|
||||
<< "," << toMBKlambda(pin->getY())
|
||||
<< "," << toMBKlambda(width)
|
||||
<< "," << toMBKName(pinName)
|
||||
<< "," << index
|
||||
<< ",";
|
||||
switch ( pin->getAccessDirection() ) {
|
||||
case Pin::AccessDirection::NORTH: ccell << "NORTH"; break;
|
||||
case Pin::AccessDirection::SOUTH: ccell << "SOUTH"; break;
|
||||
case Pin::AccessDirection::EAST: ccell << "EAST" ; break;
|
||||
case Pin::AccessDirection::WEST: ccell << "WEST" ; break;
|
||||
case Pin::AccessDirection::UNDEFINED:
|
||||
default:
|
||||
throw Error( "CRL::ApDriver(): Pin \" has undefined access direction."
|
||||
, getString(pin->getName()).c_str() );
|
||||
}
|
||||
ccell << "," << mbkLayer << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DumpDate(ofstream &ccell)
|
||||
{
|
||||
time_t tim;
|
||||
|
@ -400,6 +396,7 @@ void DumpDate(ofstream &ccell)
|
|||
<< "/" << rest->tm_year+1900;
|
||||
}
|
||||
|
||||
|
||||
void DumpInstances(ofstream &ccell, Cell* cell)
|
||||
{
|
||||
for_each_instance(instance, cell->getNotUnplacedInstances())
|
||||
|
@ -444,6 +441,7 @@ void DumpInstances(ofstream &ccell, Cell* cell)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace CRL {
|
||||
|
|
|
@ -438,14 +438,21 @@ class Side ( object ):
|
|||
|
||||
self.u += padInstance.getMasterCell().getAbutmentBox().getWidth()
|
||||
|
||||
p = None
|
||||
if self.conf.getIoPadGauge().getName() == 'pxlib':
|
||||
p = re.compile( r'p(?P<power>v[sd]{2}[ei])ck_px' )
|
||||
|
||||
if self.conf.getIoPadGauge().getName().startswith('phlib'):
|
||||
p = re.compile( r'p(?P<power>v[sd]{2})ck2_sp' )
|
||||
|
||||
if p:
|
||||
m = p.match( padInstance.getMasterCell().getName() )
|
||||
|
||||
padName = 'pad'
|
||||
if m: padName = m.group( 'power' )
|
||||
|
||||
padNet = padInstance.getMasterCell().getNet( padName )
|
||||
print 'padName:', padName, 'padNet:', padNet
|
||||
if padNet:
|
||||
plug = padInstance.getPlug( padNet )
|
||||
chipNet = plug.getNet()
|
||||
|
|
Loading…
Reference in New Issue