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:
Jean-Paul Chaput 2019-10-05 16:04:12 +02:00
parent 02b30b6681
commit 5914e16f26
2 changed files with 99 additions and 94 deletions

View File

@ -186,6 +186,7 @@ void DumpReference(ofstream& ccell, Cell *cell)
} }
} }
void DumpContacts(ofstream& ccell, Cell *cell) void DumpContacts(ofstream& ccell, Cell *cell)
{ {
const char* mbkLayer; const char* mbkLayer;
@ -232,11 +233,11 @@ void DumpContacts(ofstream& ccell, Cell *cell)
void DumpSegments ( ofstream& ccell, Cell* cell ) void DumpSegments ( ofstream& ccell, Cell* cell )
{ {
const char* mbkLayer; const char* mbkLayer = NULL;
DbU::Unit x1, x2, y1, y2, width; DbU::Unit x1, x2, y1, y2, width;
Segment* segment; Segment* segment = NULL;
RoutingPad* rp; RoutingPad* rp = NULL;
bool external; bool external = false;
for ( Net* net : cell->getNets() ) { for ( Net* net : cell->getNets() ) {
string netName = toMBKName( net->getName() ); string netName = toMBKName( net->getName() );
@ -244,18 +245,38 @@ void DumpContacts(ofstream& ccell, Cell *cell)
for ( Component* component : net->getComponents() ) { for ( Component* component : net->getComponents() ) {
if ( (rp = dynamic_cast<RoutingPad*>(component)) ) { if ( (rp = dynamic_cast<RoutingPad*>(component)) ) {
if ( not net->isExternal() ) continue; if (not net->isExternal()) continue;
if ( not cell->isRouted() ) continue; if (not cell->isRouted()) continue;
external = true; external = true;
segment = dynamic_cast<Segment*>(rp->getOccurrence().getEntity()); segment = dynamic_cast<Segment*>(rp->getOccurrence().getEntity());
if ( !segment ) continue; if (segment) {
x1 = rp->getSourceX(); x1 = rp->getSourceX();
x2 = rp->getTargetX(); x2 = rp->getTargetX();
y1 = rp->getSourceY(); y1 = rp->getSourceY();
y2 = rp->getTargetY(); y2 = rp->getTargetY();
width = segment->getWidth(); 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)) ) { } else if ( (segment = dynamic_cast<Segment*>(component)) ) {
external = NetExternalComponents::isExternal(component); external = NetExternalComponents::isExternal(component);
x1 = segment->getSourceX(); x1 = segment->getSourceX();
@ -303,48 +324,35 @@ unsigned getPinIndex(Name& pinname)
} }
} }
void DumpPins(ofstream &ccell, Cell* cell) void DumpPins(ofstream &ccell, Cell* cell)
{ {
const char* mbkLayer; const char* mbkLayer = NULL;
for_each_net(net, cell->getExternalNets()) for ( Net* net : cell->getExternalNets() ) {
{ vector<Pin*> pins;
typedef vector<Pin*> PinVector; for ( Pin* pin : net->getPins() ) {
PinVector pinVector; pins.push_back(pin);
for_each_pin(pin, net->getPins())
{
pinVector.push_back(pin);
end_for;
} }
sort (pinVector.begin(), pinVector.end(), PinSort());
sort( pins.begin(), pins.end(), PinSort() );
set<unsigned> indexesSet; set<unsigned> indexesSet;
for (PinVector::const_iterator pvit = pinVector.begin(); for ( Pin* pin : pins ) {
pvit != pinVector.end(); if (not toMBKLayer(mbkLayer,pin->getLayer()->getName(),false)) continue;
pvit++)
{
if ( !toMBKLayer(mbkLayer,(*pvit)->getLayer()->getName(),false) ) continue;
Pin* pin = *pvit; Name pinName (pin->getName());
Name pinName(pin->getName());
unsigned index = getPinIndex(pinName); unsigned index = getPinIndex(pinName);
if (pinName != net->getName()) if (pinName != net->getName()) {
{ throw Error( "CRL::ApDriver(): Pin \"%s\" and Net \"%s[.index]\" must have the same name to driven in AP format."
throw Error("Pin name (" + getString(pinName) , getString(pinName).c_str()
+ ") must look like " , getString(net->getName()).c_str() );
+ getString(net->getName())
+ "[.index] to be driven in AP format");
} }
if (indexesSet.find(index) != indexesSet.end()) if (indexesSet.find(index) != indexesSet.end())
{ throw Error( "CRL::ApDriver(): Net \"%s\" has more than one Pin indexed %u."
throw Error("Two pins on same net with same index for net : " , getString(net->getName()).c_str(), index );
+ getString(net->getName()));
}
indexesSet.insert(index); 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; DbU::Unit width = 0;
switch ( pin->getAccessDirection() ) { switch ( pin->getAccessDirection() ) {
@ -353,10 +361,6 @@ void DumpPins(ofstream &ccell, Cell* cell)
case Pin::AccessDirection::EAST: case Pin::AccessDirection::EAST:
case Pin::AccessDirection::WEST: width = pin->getHeight(); break; case Pin::AccessDirection::WEST: width = pin->getHeight(); break;
default: default:
cerr << Warning( "CRL::ApDriver(): Pin \"" + getString(pin->getName()) + "\" of \""
+ getString(net->getName())
+ "\", has undefined access direction.")
<< endl;;
break; break;
} }
@ -366,30 +370,22 @@ void DumpPins(ofstream &ccell, Cell* cell)
<< "," << toMBKName(pinName) << "," << toMBKName(pinName)
<< "," << index << "," << index
<< ","; << ",";
switch (pin->getAccessDirection()) switch ( pin->getAccessDirection() ) {
{ case Pin::AccessDirection::NORTH: ccell << "NORTH"; break;
case Pin::AccessDirection::NORTH: case Pin::AccessDirection::SOUTH: ccell << "SOUTH"; break;
ccell << "NORTH"; case Pin::AccessDirection::EAST: ccell << "EAST" ; break;
break; case Pin::AccessDirection::WEST: ccell << "WEST" ; 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: case Pin::AccessDirection::UNDEFINED:
default: default:
throw Error("Pins must a have direction to generate a .ap"); throw Error( "CRL::ApDriver(): Pin \" has undefined access direction."
, getString(pin->getName()).c_str() );
} }
ccell << "," << mbkLayer << endl; ccell << "," << mbkLayer << endl;
} }
end_for;
} }
} }
void DumpDate(ofstream &ccell) void DumpDate(ofstream &ccell)
{ {
time_t tim; time_t tim;
@ -400,6 +396,7 @@ void DumpDate(ofstream &ccell)
<< "/" << rest->tm_year+1900; << "/" << rest->tm_year+1900;
} }
void DumpInstances(ofstream &ccell, Cell* cell) void DumpInstances(ofstream &ccell, Cell* cell)
{ {
for_each_instance(instance, cell->getNotUnplacedInstances()) for_each_instance(instance, cell->getNotUnplacedInstances())
@ -444,6 +441,7 @@ void DumpInstances(ofstream &ccell, Cell* cell)
} }
} }
} }
namespace CRL { namespace CRL {

View File

@ -438,14 +438,21 @@ class Side ( object ):
self.u += padInstance.getMasterCell().getAbutmentBox().getWidth() self.u += padInstance.getMasterCell().getAbutmentBox().getWidth()
p = None
if self.conf.getIoPadGauge().getName() == 'pxlib': if self.conf.getIoPadGauge().getName() == 'pxlib':
p = re.compile( r'p(?P<power>v[sd]{2}[ei])ck_px' ) 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() ) m = p.match( padInstance.getMasterCell().getName() )
padName = 'pad' padName = 'pad'
if m: padName = m.group( 'power' ) if m: padName = m.group( 'power' )
padNet = padInstance.getMasterCell().getNet( padName ) padNet = padInstance.getMasterCell().getNet( padName )
print 'padName:', padName, 'padNet:', padNet
if padNet: if padNet:
plug = padInstance.getPlug( padNet ) plug = padInstance.getPlug( padNet )
chipNet = plug.getNet() chipNet = plug.getNet()