Compare commits
3 Commits
352ca94483
...
92a3e32aaf
Author | SHA1 | Date |
---|---|---|
|
92a3e32aaf | |
|
dd49a185af | |
|
5f60767486 |
|
@ -123,6 +123,11 @@ namespace {
|
|||
static const uint32_t IsSegSource;
|
||||
static const uint32_t InCluster;
|
||||
static string toStr ( uint32_t );
|
||||
public:
|
||||
template<typename DerivedT>
|
||||
inline const DerivedT* as () const { return dynamic_cast<const DerivedT>( this ); }
|
||||
template<typename DerivedT>
|
||||
inline DerivedT* as () { return dynamic_cast<DerivedT>( this ); }
|
||||
public:
|
||||
DiodeCluster ( AnabaticEngine*, RoutingPad* );
|
||||
virtual ~DiodeCluster ();
|
||||
|
@ -136,13 +141,17 @@ namespace {
|
|||
inline AnabaticEngine* _getAnabatic () const;
|
||||
inline const RoutingPadInfos& getRoutingPads () const;
|
||||
inline RoutingPadInfos& _getRoutingPads () ;
|
||||
inline const set<size_t>& getNeighbors () const;
|
||||
inline const vector<Instance*>& getDiodes () const;
|
||||
inline vector<Instance*>& _getDiodes ();
|
||||
inline uint32_t getForcedDiodes () const;
|
||||
inline DbU::Unit getWL () const;
|
||||
inline DbU::Unit& _getWL ();
|
||||
void showArea () const;
|
||||
virtual bool needsDiode () const = 0;
|
||||
Box getBoundingBox () const;
|
||||
inline void addNeighbor ( size_t );
|
||||
inline void addForcedDiodes ( uint32_t );
|
||||
void merge ( GCell*, uint32_t distance, GCell* back=NULL );
|
||||
virtual void merge ( RoutingPad* );
|
||||
virtual void merge ( Segment* ) = 0;
|
||||
|
@ -159,6 +168,8 @@ namespace {
|
|||
RoutingPadInfos _routingPads;
|
||||
vector<GCellArea> _areas;
|
||||
vector<Instance*> _diodes;
|
||||
set<size_t> _neighbors;
|
||||
uint32_t _forcedDiodes;
|
||||
};
|
||||
|
||||
|
||||
|
@ -187,6 +198,8 @@ namespace {
|
|||
, _routingPads()
|
||||
, _areas(1)
|
||||
, _diodes()
|
||||
, _neighbors()
|
||||
, _forcedDiodes(0)
|
||||
{
|
||||
merge( rp );
|
||||
}
|
||||
|
@ -205,6 +218,10 @@ namespace {
|
|||
inline RoutingPadInfos& DiodeCluster::_getRoutingPads () { return _routingPads; }
|
||||
inline const vector<Instance*>& DiodeCluster::getDiodes () const { return _diodes; }
|
||||
inline vector<Instance*>& DiodeCluster::_getDiodes () { return _diodes; }
|
||||
inline const set<size_t>& DiodeCluster::getNeighbors () const { return _neighbors; }
|
||||
inline void DiodeCluster::addNeighbor ( size_t neighbor ) { _neighbors.insert(neighbor); }
|
||||
inline uint32_t DiodeCluster::getForcedDiodes () const { return _forcedDiodes; }
|
||||
inline void DiodeCluster::addForcedDiodes ( uint32_t count ) { _forcedDiodes += count; }
|
||||
|
||||
|
||||
DbU::Unit DiodeCluster::getAntennaGateMaxWL () const
|
||||
|
@ -415,6 +432,7 @@ namespace {
|
|||
cdebug_log(147,1) << "DiodeCluster::createDiodes() count=" << diodeCount
|
||||
<< ", forcedHalo=" << (_areas.size()-1) << endl;
|
||||
Instance* diode = NULL;
|
||||
//for ( size_t i=(_areas.size() == 1)?0:1 ; i<_areas.size() ; ++i ) {
|
||||
for ( size_t i=0 ; i<_areas.size() ; ++i ) {
|
||||
if (i) diodeCount = 1;
|
||||
cdebug_log(147,0) << "Diode for area [" << i << "]" << endl;
|
||||
|
@ -502,6 +520,7 @@ namespace {
|
|||
|
||||
bool DiodeRps::needsDiode () const
|
||||
{
|
||||
if (getForcedDiodes()) return true;
|
||||
for ( auto& infos : getRoutingPads() ) {
|
||||
if (std::get<1>(infos) & IsSink) return true;
|
||||
}
|
||||
|
@ -526,8 +545,9 @@ namespace {
|
|||
cdebug_log(147,0) << "DiodeRps::mergeHalo(): " << segment << endl;
|
||||
if (not segment) return;
|
||||
|
||||
if ( (dynamic_cast<Horizontal*>(segment))
|
||||
and (getWL() + segment->getLength() > getAntennaGateMaxWL())) {
|
||||
// if ( (dynamic_cast<Horizontal*>(segment))
|
||||
// and (getWL() + segment->getLength() > getAntennaGateMaxWL())) {
|
||||
if (dynamic_cast<Horizontal*>(segment)) {
|
||||
cdebug_log(147,0) << " Put in forced halo." << segment << endl;
|
||||
GCellsUnder gcells = _getAnabatic()->getGCellsUnder( segment );
|
||||
if (not gcells->empty()) {
|
||||
|
@ -590,20 +610,26 @@ namespace {
|
|||
|
||||
class DiodeWire : public DiodeCluster {
|
||||
public:
|
||||
DiodeWire ( AnabaticEngine*, RoutingPad* );
|
||||
virtual bool needsDiode () const;
|
||||
virtual void merge ( Segment* );
|
||||
virtual const vector<Instance*>& createDiodes ( Etesian::Area* );
|
||||
DiodeWire ( AnabaticEngine*, RoutingPad* );
|
||||
virtual bool needsDiode () const;
|
||||
virtual void merge ( Segment* );
|
||||
virtual const vector<Instance*>& createDiodes ( Etesian::Area* );
|
||||
inline const set<Segment*,Go::CompareById>& getSegments () const;
|
||||
private:
|
||||
set<Box,CompareBySegmentBox> _boxes;
|
||||
set<Contact*,Go::CompareById> _contacts;
|
||||
set<Segment*,Go::CompareById> _segments;
|
||||
};
|
||||
|
||||
|
||||
inline const set<Segment*,Go::CompareById>& DiodeWire::getSegments () const { return _segments; }
|
||||
|
||||
|
||||
DiodeWire::DiodeWire ( AnabaticEngine* anabatic, RoutingPad* rp )
|
||||
: DiodeCluster(anabatic,rp)
|
||||
, _boxes()
|
||||
, _contacts()
|
||||
, _segments()
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -613,9 +639,10 @@ namespace {
|
|||
|
||||
void DiodeWire::merge ( Segment* segment )
|
||||
{
|
||||
if (_segments.find(segment) != _segments.end()) return;
|
||||
Box bb = segment->getBoundingBox();
|
||||
if (_boxes.find(bb) != _boxes.end()) return;
|
||||
cdebug_log(147,0) << "| merge: " << segment << endl;
|
||||
_segments.insert( segment );
|
||||
_boxes.insert( bb );
|
||||
_getWL() += segment->getLength();
|
||||
}
|
||||
|
@ -623,7 +650,14 @@ namespace {
|
|||
|
||||
const vector<Instance*>& DiodeWire::createDiodes ( Etesian::Area* area )
|
||||
{
|
||||
cdebug_log(147,1) << "DiodeWire::createDiodes() " << endl;
|
||||
cdebug_log(147,1) << "DiodeWire::createDiodes() on " << _boxes.size() << " boxes." << endl;
|
||||
|
||||
ostringstream m;
|
||||
m << "Neighbors: [";
|
||||
for ( size_t neighbor : getNeighbors() ) { m << " " << neighbor; }
|
||||
m << " ]";
|
||||
cdebug_log(147,0) << m.str() << endl;
|
||||
|
||||
DbU::Unit antennaDiodeMaxWL = getAntennaDiodeMaxWL();
|
||||
|
||||
size_t diodeCount = getWL() / antennaDiodeMaxWL;
|
||||
|
@ -635,7 +669,7 @@ namespace {
|
|||
size_t segDiodeCount = bbLength / antennaDiodeMaxWL;
|
||||
if (not segDiodeCount) ++segDiodeCount;
|
||||
bool isH = (bb.getWidth() >= bb.getHeight());
|
||||
cdebug_log(147,0) << "diodes=" << segDiodeCount << " " << bb
|
||||
cdebug_log(147,0) << "Processing wire diodes=" << segDiodeCount << " " << bb
|
||||
<< " isH=" << isH
|
||||
<< " length:" << DbU::getValueString(getBoxLength(bb)) << endl;
|
||||
//if (bbLength < antennaDiodeMaxWL/4) continue;
|
||||
|
@ -647,7 +681,6 @@ namespace {
|
|||
_createDiode( area, bb, uHint );
|
||||
uHint += antennaDiodeMaxWL;
|
||||
}
|
||||
if (_getDiodes().size() >= diodeCount) break;
|
||||
} else {
|
||||
GCellsUnder gcells = _getAnabatic()->getGCellsUnder( Point(bb.getXCenter(),bb.getYMin())
|
||||
, Point(bb.getXCenter(),bb.getYMax()) );
|
||||
|
@ -661,6 +694,11 @@ namespace {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_getDiodes().size() >= diodeCount) {
|
||||
cdebug_log(147,0) << "Added enough diodes " << _getDiodes().size() << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_getDiodes().size() < diodeCount) {
|
||||
|
@ -804,9 +842,9 @@ namespace Anabatic {
|
|||
|
||||
DbU::Unit antennaGateMaxWL = etesian->getAntennaGateMaxWL();
|
||||
|
||||
vector<DiodeCluster*> clusters;
|
||||
set<RoutingPad*,DBo::CompareById> rpsDone;
|
||||
set<Segment*,DBo::CompareById> clusterSegments;
|
||||
vector<DiodeCluster*> clusters;
|
||||
map<RoutingPad*,size_t,DBo::CompareById> rpsDone;
|
||||
map<Segment*,size_t,DBo::CompareById> clusterSegments;
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
set<Segment*,DBo::CompareById> segmentsDone;
|
||||
|
||||
|
@ -815,7 +853,7 @@ namespace Anabatic {
|
|||
cdebug_log(147,0) << "New Cluster [" << clusters.size() << "] from " << rp << endl;
|
||||
DiodeCluster* cluster = new DiodeRps ( this, rp );
|
||||
clusters.push_back( cluster );
|
||||
rpsDone.insert( rp );
|
||||
rpsDone.insert( make_pair( rp, clusters.size()-1 ) );
|
||||
|
||||
size_t stackTop = 0;
|
||||
vector< StackItem > hooksStack;
|
||||
|
@ -861,7 +899,7 @@ namespace Anabatic {
|
|||
if (rpsDone.find(toRp) == rpsDone.end()) {
|
||||
cdebug_log(147,0) << "> Agglomerate " << toRp << endl;
|
||||
cluster->merge( toRp );
|
||||
rpsDone.insert( toRp );
|
||||
rpsDone.insert( make_pair( toRp, clusters.size()-1 ) );
|
||||
rp = toRp;
|
||||
}
|
||||
}
|
||||
|
@ -876,7 +914,7 @@ namespace Anabatic {
|
|||
else branchWL = 0;
|
||||
cluster->merge( segment );
|
||||
std::get<3>( hooksStack[backIndex] ) |= DiodeCluster::InCluster;
|
||||
clusterSegments.insert( segment );
|
||||
clusterSegments.insert( make_pair( segment, clusters.size()-1 ) );
|
||||
cdebug_log(147,0) << "| back=" << backIndex
|
||||
<< " -> " << std::get<2>( hooksStack[backIndex] )
|
||||
<< " " << DbU::getValueString(segment->getLength())
|
||||
|
@ -931,7 +969,9 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
if (clusters.size() > 1) {
|
||||
cdebug_log(147,0) << "Cluster wiring" << endl;
|
||||
size_t rpClustersSize = clusters.size();
|
||||
|
||||
cdebug_log(147,0) << "Cluster wiring, rpClustersSize=" << rpClustersSize << endl;
|
||||
for ( Segment* segment : net->getSegments() ) {
|
||||
if (clusterSegments.find(segment) != clusterSegments.end()) continue;
|
||||
|
||||
|
@ -940,7 +980,7 @@ namespace Anabatic {
|
|||
DiodeWire* cluster = new DiodeWire( this, clusters[0]->getRefRp() );
|
||||
cluster->merge( segment );
|
||||
clusters.push_back( cluster );
|
||||
clusterSegments.insert( segment );
|
||||
clusterSegments.insert( make_pair( segment, clusters.size()-1 ) );
|
||||
|
||||
size_t stackTop = 0;
|
||||
vector< StackItem > hooksStack;
|
||||
|
@ -959,8 +999,15 @@ namespace Anabatic {
|
|||
|
||||
bool hasRp = false;
|
||||
for ( Hook* hook : toHook->getHooks() ) {
|
||||
if (dynamic_cast<RoutingPad*>(hook->getComponent())) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( hook->getComponent() );
|
||||
if (rp) {
|
||||
hasRp = true;
|
||||
auto irp = rpsDone.find( rp );
|
||||
if (irp != rpsDone.end()) {
|
||||
size_t neighbor = (*irp).second;
|
||||
cdebug_log(147,0) << "| " << rp << " belongs to [" << neighbor << "]" << endl;
|
||||
cluster->addNeighbor( neighbor );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -970,8 +1017,15 @@ namespace Anabatic {
|
|||
Segment* segment = dynamic_cast<Segment*>( hook->getComponent() );
|
||||
if (segment) {
|
||||
if (segment == fromSegment) continue;
|
||||
if (clusterSegments.find(segment) != clusterSegments.end()) continue;
|
||||
clusterSegments.insert( segment );
|
||||
auto iclusterSegment = clusterSegments.find( segment );
|
||||
if (iclusterSegment != clusterSegments.end()) {
|
||||
size_t neighbor = (*iclusterSegment).second;
|
||||
cdebug_log(147,0) << "| " << segment << " belongs to [" << neighbor << "]" << endl;
|
||||
if (neighbor < rpClustersSize)
|
||||
cluster->addNeighbor( neighbor );
|
||||
continue;
|
||||
}
|
||||
clusterSegments.insert( make_pair( segment, clusters.size()-1 ) );
|
||||
cluster->merge( segment );
|
||||
uint32_t flags = (segment->getSourceHook() == hook) ? DiodeCluster::IsSegSource : 0;
|
||||
if (dynamic_cast<Segment::SourceHook*>(hook)) {
|
||||
|
@ -989,7 +1043,8 @@ namespace Anabatic {
|
|||
|
||||
total += clusters.size();
|
||||
cdebug_log(147,1) << "Net \"" << net->getName() << " has " << clusters.size() << " diode clusters." << endl;
|
||||
for ( size_t i=0 ; i<clusters.size() ; ++i ) {
|
||||
size_t i = clusters.size()-1;
|
||||
while ( true ) {
|
||||
cdebug_log(147,1) << "Cluster [" << i << "] needsDiode=" << clusters[i]->needsDiode()
|
||||
<< " bb=" << clusters[i]->getBoundingBox() << endl;
|
||||
cdebug_log(147,0) << " WL=" << DbU::getValueString(clusters[i]->getWL()) << endl;
|
||||
|
@ -997,25 +1052,29 @@ namespace Anabatic {
|
|||
cdebug_log(147,0) << "| flags=" << DiodeCluster::toStr(std::get<1>(item))
|
||||
<< " " << std::get<0>(item) << endl;
|
||||
}
|
||||
if (not clusters[i]->needsDiode()) {
|
||||
cdebug_tabw(147,-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const vector<Instance*>& diodes = clusters[i]->createDiodes( etesian->getArea() );
|
||||
if (not diodes.empty()) {
|
||||
clusters[i]->connectDiodes();
|
||||
} else {
|
||||
cerr << Error( "EtesianEngine::antennaProtect(): For %s (rps:%u, clusters:%u)\n"
|
||||
" Cannot find a diode nearby %s."
|
||||
, getString(net).c_str()
|
||||
, rpsDone.size()
|
||||
, clusters.size()
|
||||
, getString(clusters[i]->getRefRp()).c_str()
|
||||
) << endl;
|
||||
failed += 1;
|
||||
|
||||
if (clusters[i]->needsDiode()) {
|
||||
const vector<Instance*>& diodes = clusters[i]->createDiodes( etesian->getArea() );
|
||||
if (not diodes.empty()) {
|
||||
clusters[i]->connectDiodes();
|
||||
} else {
|
||||
cerr << Error( "EtesianEngine::antennaProtect(): For %s (rps:%u, clusters:%u)\n"
|
||||
" Cannot find a diode nearby %s."
|
||||
, getString(net).c_str()
|
||||
, rpsDone.size()
|
||||
, clusters.size()
|
||||
, getString(clusters[i]->getRefRp()).c_str()
|
||||
) << endl;
|
||||
failed += 1;
|
||||
for ( size_t icluster : clusters[i]->getNeighbors() ) {
|
||||
clusters[icluster]->addForcedDiodes( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(147,-1);
|
||||
if (i == 0) break;
|
||||
--i;
|
||||
}
|
||||
|
||||
cdebug_tabw(147,-1);
|
||||
|
|
|
@ -1697,8 +1697,13 @@ namespace Anabatic {
|
|||
return false;
|
||||
}
|
||||
|
||||
DbU::Unit oneGrid = DbU::fromGrid( 1 );
|
||||
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
|
||||
DbU::Unit sourceExpand = - (techMinLength - segMinLength) / 2 - sourceCap;
|
||||
if (targetExpand % oneGrid)
|
||||
targetExpand += oneGrid - targetExpand % oneGrid;
|
||||
if (sourceExpand % oneGrid)
|
||||
sourceExpand -= oneGrid + sourceExpand % oneGrid;
|
||||
if (not span.isEmpty()) {
|
||||
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand);
|
||||
if (shiftLeft < 0) {
|
||||
|
|
|
@ -513,6 +513,7 @@ class CoreWire ( object ):
|
|||
self.offset = 0
|
||||
self.offsetType = CoreWire.NoOffset
|
||||
self.side = side
|
||||
self.addJumper = False
|
||||
self.preferredDir = preferredDir
|
||||
self.inCoronaRange = True
|
||||
self.arraySize = None
|
||||
|
@ -520,6 +521,8 @@ class CoreWire ( object ):
|
|||
self.viaPitch = DbU.fromLambda( 4.0 )
|
||||
self.gapWidth = 0
|
||||
self._computeCoreLayers()
|
||||
if self.conf.routingGauge.getName() == 'FlexLib':
|
||||
self.addJumper = True
|
||||
|
||||
@property
|
||||
def conf ( self ): return self.corona.conf
|
||||
|
@ -627,13 +630,68 @@ class CoreWire ( object ):
|
|||
if not self.preferredDir:
|
||||
#xPadMin -= self.bbSegment.getHeight()/2
|
||||
xPadMin -= 3*vPitch
|
||||
hReal = Horizontal.create( self.chipNet
|
||||
, self.padSegment.getLayer()
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, self.bbSegment.getHeight()
|
||||
, xPadMin
|
||||
, xPadMax
|
||||
)
|
||||
if self.addJumper:
|
||||
rg = self.conf.routingGauge
|
||||
gaugeM5 = rg.getLayerGauge( 4 )
|
||||
wwidthM5 = gaugeM5.getWireWidth()
|
||||
jumperGap = 3*gaugeM5.getPitch()
|
||||
if self.side == East:
|
||||
gapCenter = xPadMin + 5*gaugeM5.getPitch()
|
||||
else:
|
||||
gapCenter = xPadMax - 5*gaugeM5.getPitch()
|
||||
xJumpMin = gapCenter - jumperGap/2
|
||||
xJumpMax = gapCenter + jumperGap/2
|
||||
hReal1 = Horizontal.create( self.chipNet
|
||||
, self.padSegment.getLayer()
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, self.bbSegment.getHeight()
|
||||
, xPadMin
|
||||
, xJumpMin
|
||||
)
|
||||
trace( 550, '\thReal1: %s\n' % str(hReal1) )
|
||||
hReal2 = Horizontal.create( self.chipNet
|
||||
, self.padSegment.getLayer()
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, self.bbSegment.getHeight()
|
||||
, xJumpMax
|
||||
, xPadMax
|
||||
)
|
||||
trace( 550, '\thReal2: %s\n' % str(hReal2) )
|
||||
hReal = hReal2 if self.side == West else hReal1
|
||||
bvia1 = BigVia( self.chipNet
|
||||
, rg.getLayerDepth( self.padSegment.getLayer() )
|
||||
, xJumpMin
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, wwidthM5
|
||||
, 2*wwidthM5
|
||||
, flags=BigVia.AllowAllExpand )
|
||||
bvia1.mergeDepth( gaugeM5.getDepth() )
|
||||
trace( 550, '\tbvia1: %s\n' % str(bvia1) )
|
||||
bvia1.doLayout()
|
||||
bvia2 = BigVia( self.chipNet
|
||||
, rg.getLayerDepth( self.padSegment.getLayer() )
|
||||
, xJumpMax
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, wwidthM5
|
||||
, 2*wwidthM5
|
||||
, flags=BigVia.AllowAllExpand )
|
||||
bvia2.mergeDepth( gaugeM5.getDepth() )
|
||||
bvia2.doLayout()
|
||||
trace( 550, '\tbvia2: %s\n' % str(bvia2) )
|
||||
Horizontal.create( bvia1.getPlate( gaugeM5.getLayer() )
|
||||
, bvia2.getPlate( gaugeM5.getLayer() )
|
||||
, gaugeM5.getLayer()
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, wwidthM5
|
||||
)
|
||||
else:
|
||||
hReal = Horizontal.create( self.chipNet
|
||||
, self.padSegment.getLayer()
|
||||
, self.bbSegment.getCenter().getY()
|
||||
, self.bbSegment.getHeight()
|
||||
, xPadMin
|
||||
, xPadMax
|
||||
)
|
||||
trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) )
|
||||
if self.arraySize:
|
||||
contacts = self.conf.coronaContactArray( self.chipNet
|
||||
|
|
|
@ -134,19 +134,33 @@ class Macro ( object ):
|
|||
gaugeMetal2 = self.rg.getLayerGauge( 1 )
|
||||
gaugeMetal3 = self.rg.getLayerGauge( 2 )
|
||||
gaugeMetal4 = self.rg.getLayerGauge( 3 )
|
||||
gaugeMetal5 = self.rg.getLayerGauge( 4 )
|
||||
blockageMetal2 = gaugeMetal2.getBlockageLayer()
|
||||
blockageMetal3 = gaugeMetal3.getBlockageLayer()
|
||||
blockageMetal4 = gaugeMetal4.getBlockageLayer()
|
||||
minSpacingMetal2 = gaugeMetal2.getLayer().getMinimalSpacing()
|
||||
minSpacingMetal3 = gaugeMetal3.getLayer().getMinimalSpacing()
|
||||
minSpacingMetal4 = gaugeMetal4.getLayer().getMinimalSpacing()
|
||||
useJumper = False
|
||||
xMinAdjust = 0
|
||||
yMinAdjust = 0
|
||||
xMaxAdjust = 0
|
||||
yMaxAdjust = 0
|
||||
if self.cell.getName().lower() == 'spblock_512w64b8w':
|
||||
print( ' o Ad-hoc patch for "{}".'.format(self.cell.getName()) )
|
||||
useJumper = True
|
||||
xMinAdjust = 3*self.rg.getPitch( gaugeMetal5.getLayer() )
|
||||
pitch = gaugeMetal2.getPitch()
|
||||
if xMinAdjust % pitch:
|
||||
xMinAdjust += pitch - (xMinAdjust % pitch)
|
||||
for net in self.cell.getNets():
|
||||
for component in net.getComponents():
|
||||
if isinstance(component,Rectilinear) and component.getLayer() == blockageMetal2:
|
||||
bb = component.getBoundingBox()
|
||||
bb.inflate( minSpacingMetal2 )
|
||||
bb.inflate( minSpacingMetal2 + xMinAdjust
|
||||
, minSpacingMetal2
|
||||
, minSpacingMetal2
|
||||
, minSpacingMetal2 )
|
||||
Horizontal.create( component.getNet()
|
||||
, blockageMetal2
|
||||
, bb.getYCenter()
|
||||
|
@ -192,11 +206,9 @@ class Macro ( object ):
|
|||
elif ab.getXMin() == bb.getXMin(): westPins.append( component )
|
||||
elif ab.getYMax() == bb.getYMax(): northPins.append( component )
|
||||
elif ab.getYMin() == bb.getYMin(): southPins.append( component )
|
||||
xAdjust = 0
|
||||
yAdjust = 0
|
||||
if ab.getWidth () % sliceHeight: xAdjust = sliceHeight - ab.getWidth () % sliceHeight
|
||||
if ab.getHeight() % sliceHeight: yAdjust = sliceHeight - ab.getHeight() % sliceHeight
|
||||
self.innerAb.inflate( 0, 0, xAdjust, yAdjust )
|
||||
if ab.getWidth () % sliceHeight: xMaxAdjust = sliceHeight - (ab.getWidth ()+xMinAdjust) % sliceHeight
|
||||
if ab.getHeight() % sliceHeight: yMaxAdjust = sliceHeight - (ab.getHeight()+yMinAdjust) % sliceHeight
|
||||
self.innerAb.inflate( xMinAdjust, 0, xMaxAdjust, yMaxAdjust )
|
||||
self.outerAb = Box( self.innerAb )
|
||||
self.outerAb.inflate( sliceHeight )
|
||||
westPins .sort( key=lambda k: k.getBoundingBox().getYCenter() )
|
||||
|
@ -225,27 +237,78 @@ class Macro ( object ):
|
|||
else:
|
||||
ppYAxis += width/2
|
||||
ppYOngrid -= wwidth/2
|
||||
vertical = Vertical.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, bb.getXMin()
|
||||
, width
|
||||
, ppYAxis
|
||||
, ppYOngrid
|
||||
)
|
||||
horizontal = Horizontal.create( component.getNet()
|
||||
if useJumper:
|
||||
jpitch = self.rg.getPitch ( gaugeMetal5.getLayer() )
|
||||
jwwidth = self.rg.getWireWidth( gaugeMetal5.getLayer() )
|
||||
xMin -= 4*jpitch
|
||||
bvia1 = BigVia( component.getNet()
|
||||
, self.getLayerDepth(component.getLayer())
|
||||
, xMax
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, 3*wwidth
|
||||
, flags=BigVia.AllowAllExpand )
|
||||
bvia1.mergeDepth( gaugeMetal5.getDepth() )
|
||||
bvia1.doLayout()
|
||||
bvia2 = BigVia( component.getNet()
|
||||
, self.getLayerDepth(component.getLayer())
|
||||
, xMax - 3*jpitch
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, 3*wwidth
|
||||
, flags=BigVia.AllowAllExpand )
|
||||
bvia2.mergeDepth( gaugeMetal5.getDepth() )
|
||||
bvia2.doLayout()
|
||||
Horizontal.create( bvia1.getPlate( gaugeMetal5.getLayer() )
|
||||
, bvia2.getPlate( gaugeMetal5.getLayer() )
|
||||
, gaugeMetal5.getLayer()
|
||||
, yOngrid
|
||||
, jwwidth
|
||||
)
|
||||
horizontal = Horizontal.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin
|
||||
, xMax - 3*jpitch
|
||||
)
|
||||
horizontal = Horizontal.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin
|
||||
, xMin + ppitch + ppitch/2
|
||||
)
|
||||
blockageNet = self.cell.getNet( '*' )
|
||||
for gauge in [ gaugeMetal3, gaugeMetal3, gaugeMetal4, gaugeMetal5 ]:
|
||||
bb = bvia1.getPlate( gauge.getLayer() ).getBoundingBox()
|
||||
bb.merge( bvia2.getPlate( gauge.getLayer() ).getBoundingBox() )
|
||||
bb.inflate( gauge.getLayer().getMinimalSpacing() )
|
||||
Pad.create( blockageNet
|
||||
, gauge.getLayer().getBlockageLayer()
|
||||
, bb )
|
||||
else:
|
||||
vertical = Vertical.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin
|
||||
, xMax
|
||||
)
|
||||
horizontal = Horizontal.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin
|
||||
, xMin + ppitch + ppitch/2
|
||||
, bb.getXMin()
|
||||
, width
|
||||
, ppYAxis
|
||||
, ppYOngrid
|
||||
)
|
||||
horizontal = Horizontal.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin
|
||||
, xMax
|
||||
)
|
||||
horizontal = Horizontal.create( component.getNet()
|
||||
, component.getLayer()
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin
|
||||
, xMin + ppitch + ppitch/2
|
||||
)
|
||||
NetExternalComponents.setExternal( horizontal )
|
||||
for component in eastPins:
|
||||
layer = component.getLayer()
|
||||
|
@ -259,8 +322,8 @@ class Macro ( object ):
|
|||
bb = component.getBoundingBox()
|
||||
yAxis = bb.getYCenter()
|
||||
yOngrid = self.getNearestTrackAxis( layer, yAxis )
|
||||
xMin = self.innerAb.getXMax() - xAdjust
|
||||
xMax = xMin + xAdjust + hMargin*ppitch
|
||||
xMin = self.innerAb.getXMax() - xMaxAdjust
|
||||
xMax = xMin + xMaxAdjust + hMargin*ppitch
|
||||
width = bb.getHeight()
|
||||
ppYAxis = yAxis
|
||||
ppYOngrid = yOngrid
|
||||
|
@ -289,7 +352,7 @@ class Macro ( object ):
|
|||
, layer
|
||||
, yOngrid
|
||||
, wwidth
|
||||
, xMin + xAdjust + ppitch
|
||||
, xMin + xMaxAdjust + ppitch
|
||||
, xMax
|
||||
)
|
||||
NetExternalComponents.setExternal( horizontal )
|
||||
|
@ -347,8 +410,8 @@ class Macro ( object ):
|
|||
bb = component.getBoundingBox()
|
||||
xAxis = bb.getXCenter()
|
||||
xOngrid = self.getNearestTrackAxis( layer, xAxis )
|
||||
yMin = self.innerAb.getYMax() - yAdjust
|
||||
yMax = yMin + yAdjust + vMargin*ppitch
|
||||
yMin = self.innerAb.getYMax() - yMaxAdjust
|
||||
yMax = yMin + yMaxAdjust + vMargin*ppitch
|
||||
width = bb.getWidth()
|
||||
ppXAxis = xAxis
|
||||
ppXOngrid = xOngrid
|
||||
|
@ -388,7 +451,7 @@ class Macro ( object ):
|
|||
, layer
|
||||
, xOngrid
|
||||
, wwidth
|
||||
, yMin + ppitch + yAdjust
|
||||
, yMin + ppitch + yMaxAdjust
|
||||
, yMax
|
||||
)
|
||||
NetExternalComponents.setExternal( vertical )
|
||||
|
|
Loading…
Reference in New Issue