More accurate antenna management in Anabatic.
* New: In Anabatic::DiodeWire, use "antennaDiodeMaxWL" to compute the number of diodes to insert in a wire only cluster. Use boxes instead of segments to define the area as segments can be splitted by the diodes inserteds at the DiodeRps stage. * New: In DiodeWire::createDiodes(), specific diode insertion method. Try to instert first in long horizontal wires.
This commit is contained in:
parent
dbdef9901f
commit
d4c3cf7dbb
|
@ -108,6 +108,10 @@ namespace {
|
|||
typedef set<GCellInfosItem,CompareGCellInfos> GCellArea;
|
||||
|
||||
|
||||
inline DbU::Unit getBoxLength ( const Box& bb )
|
||||
{ return (bb.getWidth() > bb.getHeight()) ? bb.getWidth() : bb.getHeight(); }
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "::DiodeCluster".
|
||||
|
||||
|
@ -122,7 +126,8 @@ namespace {
|
|||
public:
|
||||
DiodeCluster ( AnabaticEngine*, RoutingPad* );
|
||||
virtual ~DiodeCluster ();
|
||||
DbU::Unit getAntennaMaxWL () const;
|
||||
DbU::Unit getAntennaGateMaxWL () const;
|
||||
DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
inline bool hasRp ( RoutingPad* ) const;
|
||||
bool hasGCell ( GCell* ) const;
|
||||
inline Net* getTopNet () const;
|
||||
|
@ -202,11 +207,19 @@ namespace {
|
|||
inline vector<Instance*>& DiodeCluster::_getDiodes () { return _diodes; }
|
||||
|
||||
|
||||
DbU::Unit DiodeCluster::getAntennaMaxWL () const
|
||||
DbU::Unit DiodeCluster::getAntennaGateMaxWL () const
|
||||
{
|
||||
EtesianEngine* etesian = static_cast<EtesianEngine*>
|
||||
( ToolEngine::get( _getAnabatic()->getCell(), EtesianEngine::staticGetName() ));
|
||||
return etesian->getAntennaMaxWL();
|
||||
return etesian->getAntennaGateMaxWL();
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit DiodeCluster::getAntennaDiodeMaxWL () const
|
||||
{
|
||||
EtesianEngine* etesian = static_cast<EtesianEngine*>
|
||||
( ToolEngine::get( _getAnabatic()->getCell(), EtesianEngine::staticGetName() ));
|
||||
return etesian->getAntennaDiodeMaxWL();
|
||||
}
|
||||
|
||||
|
||||
|
@ -393,13 +406,13 @@ namespace {
|
|||
{
|
||||
if (not needsDiode()) return _diodes;
|
||||
|
||||
DbU::Unit antennaMaxWL = getAntennaMaxWL();
|
||||
size_t diodeCount = getWL() / antennaMaxWL;
|
||||
DbU::Unit antennaDiodeMaxWL = getAntennaDiodeMaxWL();
|
||||
size_t diodeCount = getWL() / antennaDiodeMaxWL;
|
||||
if (not diodeCount) diodeCount = 1;
|
||||
|
||||
showArea();
|
||||
|
||||
cdebug_log(147,1) << "DiodeCluster::createDiode() count=" << diodeCount
|
||||
cdebug_log(147,1) << "DiodeCluster::createDiodes() count=" << diodeCount
|
||||
<< ", forcedHalo=" << (_areas.size()-1) << endl;
|
||||
Instance* diode = NULL;
|
||||
for ( size_t i=0 ; i<_areas.size() ; ++i ) {
|
||||
|
@ -514,12 +527,12 @@ namespace {
|
|||
if (not segment) return;
|
||||
|
||||
if ( (dynamic_cast<Horizontal*>(segment))
|
||||
and (getWL() + segment->getLength() > getAntennaMaxWL())) {
|
||||
and (getWL() + segment->getLength() > getAntennaGateMaxWL())) {
|
||||
cdebug_log(147,0) << " Put in forced halo." << segment << endl;
|
||||
GCellsUnder gcells = _getAnabatic()->getGCellsUnder( segment );
|
||||
if (not gcells->empty()) {
|
||||
size_t iarea = _getAreas().size();
|
||||
size_t count = std::min( gcells->size(), (size_t)10 );
|
||||
size_t count = std::min( gcells->size(), (size_t)50 );
|
||||
for ( size_t i=0 ; i<count ; ++i ) {
|
||||
size_t igcell = (flags & IsSegSource) ? i : (gcells->size()-1-i);
|
||||
DiodeCluster::mergeForcedHalo( iarea, gcells->gcellAt(igcell), i );
|
||||
|
@ -595,7 +608,7 @@ namespace {
|
|||
|
||||
|
||||
bool DiodeWire::needsDiode () const
|
||||
{ return getWL() > getAntennaMaxWL(); }
|
||||
{ return getWL() >= getAntennaDiodeMaxWL(); }
|
||||
|
||||
|
||||
void DiodeWire::merge ( Segment* segment )
|
||||
|
@ -610,33 +623,36 @@ namespace {
|
|||
|
||||
const vector<Instance*>& DiodeWire::createDiodes ( Etesian::Area* area )
|
||||
{
|
||||
cdebug_log(147,1) << "DiodeWire::createDiode() " << endl;
|
||||
DbU::Unit antennaMaxWL = getAntennaMaxWL();
|
||||
cdebug_log(147,1) << "DiodeWire::createDiodes() " << endl;
|
||||
DbU::Unit antennaDiodeMaxWL = getAntennaDiodeMaxWL();
|
||||
|
||||
size_t diodeCount = getWL() / antennaMaxWL;
|
||||
size_t diodeCount = getWL() / antennaDiodeMaxWL;
|
||||
if (not diodeCount) return _getDiodes();
|
||||
|
||||
for ( const Box& bb : _boxes ) {
|
||||
bool bbH = (bb.getWidth() >= bb.getHeight());
|
||||
DbU::Unit bbLength = (bbH) ? bb.getWidth() : bb.getHeight();
|
||||
size_t segDiodeCount = bbLength / antennaMaxWL;
|
||||
size_t segDiodeCount = bbLength / antennaDiodeMaxWL;
|
||||
if (not segDiodeCount) ++segDiodeCount;
|
||||
cdebug_log(147,0) << "diodes=" << segDiodeCount << " " << bb << endl;
|
||||
if (bbLength < antennaMaxWL/4) continue;
|
||||
bool isH = (bb.getWidth() >= bb.getHeight());
|
||||
cdebug_log(147,0) << "diodes=" << segDiodeCount << " " << bb
|
||||
<< " isH=" << isH
|
||||
<< " length:" << DbU::getValueString(getBoxLength(bb)) << endl;
|
||||
//if (bbLength < antennaDiodeMaxWL/4) continue;
|
||||
|
||||
if (bbH) {
|
||||
DbU::Unit uHint = bb.getXMin();
|
||||
DbU::Unit uMax = bb.getXMax();
|
||||
while ( uHint < uMax ) {
|
||||
_createDiode( area, bb, uHint );
|
||||
uHint += antennaMaxWL;
|
||||
uHint += antennaDiodeMaxWL;
|
||||
}
|
||||
if (_getDiodes().size() >= diodeCount) break;
|
||||
} else {
|
||||
GCellsUnder gcells = _getAnabatic()->getGCellsUnder( Point(bb.getXCenter(),bb.getYMin())
|
||||
, Point(bb.getXCenter(),bb.getYMax()) );
|
||||
if (gcells->size()) {
|
||||
size_t gcellPeriod = antennaMaxWL / gcells->gcellAt(0)->getHeight();
|
||||
size_t gcellPeriod = antennaDiodeMaxWL / gcells->gcellAt(0)->getHeight();
|
||||
for ( size_t i=0 ; i<gcells->size() ; ++i ) {
|
||||
Instance* diode = _createDiode( area, gcells->gcellAt(i), NULL );
|
||||
if (diode) {
|
||||
|
@ -786,7 +802,7 @@ namespace Anabatic {
|
|||
EtesianEngine* etesian = static_cast<EtesianEngine*>
|
||||
( ToolEngine::get( getCell(), EtesianEngine::staticGetName() ));
|
||||
|
||||
DbU::Unit antennaMaxWL = etesian->getAntennaMaxWL();
|
||||
DbU::Unit antennaGateMaxWL = etesian->getAntennaGateMaxWL();
|
||||
|
||||
vector<DiodeCluster*> clusters;
|
||||
set<RoutingPad*,DBo::CompareById> rpsDone;
|
||||
|
@ -796,7 +812,7 @@ namespace Anabatic {
|
|||
|
||||
if (rpsDone.find(rp) != rpsDone.end()) continue;
|
||||
|
||||
cdebug_log(147,0) << "New cluster [" << clusters.size() << "] from " << rp << endl;
|
||||
cdebug_log(147,0) << "New Cluster [" << clusters.size() << "] from " << rp << endl;
|
||||
DiodeCluster* cluster = new DiodeRps ( this, rp );
|
||||
clusters.push_back( cluster );
|
||||
rpsDone.insert( rp );
|
||||
|
@ -814,7 +830,7 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(147,0) << "| PROCESS [" << stackTop << "] " << fromSegment << endl;
|
||||
if (fromSegment) {
|
||||
if (fromSegment->getLength() > antennaMaxWL/2) {
|
||||
if (fromSegment->getLength() > antennaGateMaxWL/2) {
|
||||
cdebug_log(147,0) << "| Long connecting wire, skipping" << endl;
|
||||
++stackTop;
|
||||
continue;
|
||||
|
@ -832,7 +848,7 @@ namespace Anabatic {
|
|||
cdebug_log(147,0) << "| wl=" << DbU::getValueString(cluster->getWL())
|
||||
<< " + " << DbU::getValueString(branchWL) << endl;
|
||||
|
||||
if (cluster->getWL() + branchWL > antennaMaxWL) {
|
||||
if (cluster->getWL() + branchWL > antennaGateMaxWL) {
|
||||
cdebug_log(147,0) << "| Cluster above maximul WL, skipping" << endl;
|
||||
++stackTop;
|
||||
continue;
|
||||
|
@ -919,7 +935,8 @@ namespace Anabatic {
|
|||
for ( Segment* segment : net->getSegments() ) {
|
||||
if (clusterSegments.find(segment) != clusterSegments.end()) continue;
|
||||
|
||||
cdebug_log(147,0) << "New wiring cluster from " << segment << endl;
|
||||
cdebug_log(147,0) << "New Cluster [" << clusters.size()
|
||||
<< "] wiring from " << segment << endl;
|
||||
DiodeWire* cluster = new DiodeWire( this, clusters[0]->getRefRp() );
|
||||
cluster->merge( segment );
|
||||
clusters.push_back( cluster );
|
||||
|
@ -940,6 +957,15 @@ namespace Anabatic {
|
|||
Hook* toHook = std::get<0>( hooksStack[stackTop] );
|
||||
Segment* fromSegment = std::get<1>( hooksStack[stackTop] );
|
||||
|
||||
bool hasRp = false;
|
||||
for ( Hook* hook : toHook->getHooks() ) {
|
||||
if (dynamic_cast<RoutingPad*>(hook->getComponent())) {
|
||||
hasRp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (not hasRp) {
|
||||
for ( Hook* hook : toHook->getHooks() ) {
|
||||
Segment* segment = dynamic_cast<Segment*>( hook->getComponent() );
|
||||
if (segment) {
|
||||
|
@ -955,6 +981,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++stackTop;
|
||||
}
|
||||
|
@ -1015,7 +1042,7 @@ namespace Anabatic {
|
|||
}
|
||||
EtesianEngine* etesian = static_cast<EtesianEngine*>
|
||||
( ToolEngine::get( getCell(), EtesianEngine::staticGetName() ));
|
||||
DbU::Unit segmentMaxWL = etesian->getAntennaMaxWL() / 2;
|
||||
DbU::Unit segmentMaxWL = etesian->getAntennaDiodeMaxWL() / 2;
|
||||
|
||||
if (not etesian->getDiodeCell()) {
|
||||
cerr << Warning( "AnabaticEngine::antennaProtect(): No diode cell found, skipped." ) << endl;
|
||||
|
@ -1033,8 +1060,9 @@ namespace Anabatic {
|
|||
if (net->isClock ()) continue;
|
||||
antennaProtect( net, failed, total );
|
||||
}
|
||||
cmess2 << Dots::asString ( " - Antenna maximum WL" , DbU::getValueString(etesian->getAntennaMaxWL()) ) << endl;
|
||||
cmess2 << Dots::asString ( " - Segment maximum WL" , DbU::getValueString(segmentMaxWL) ) << endl;
|
||||
cmess2 << Dots::asString ( " - Antenna gate maximum WL" , DbU::getValueString(etesian->getAntennaGateMaxWL()) ) << endl;
|
||||
cmess2 << Dots::asString ( " - Antenna diode maximum WL" , DbU::getValueString(etesian->getAntennaDiodeMaxWL()) ) << endl;
|
||||
cmess2 << Dots::asString ( " - Antenna segment maximum WL", DbU::getValueString(segmentMaxWL) ) << endl;
|
||||
cmess2 << Dots::asInt ( " - Total needed diodes", total ) << endl;
|
||||
cmess2 << Dots::asInt ( " - Failed to allocate" , failed ) << endl;
|
||||
cmess2 << Dots::asPercentage( " - Success ratio" , (float)(total-failed)/(float)total ) << endl;
|
||||
|
|
|
@ -89,9 +89,10 @@ namespace Anabatic {
|
|||
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" , -10.0)->asDouble())
|
||||
, _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble())
|
||||
, _edgeHScaling (Cfg::getParamDouble("anabatic.edgeHScaling" , 1.0)->asDouble())
|
||||
, _globalIterations(Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
|
||||
, _globalIterations (Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
|
||||
, _diodeName (Cfg::getParamString("etesian.diodeName" , "dio_x0")->asString() )
|
||||
, _antennaMaxWL (Cfg::getParamInt ("etesian.antennaMaxWL" , 0 )->asInt())
|
||||
, _antennaGateMaxWL (Cfg::getParamInt ("etesian.antennaGateMaxWL" , 0 )->asInt())
|
||||
, _antennaDiodeMaxWL(Cfg::getParamInt ("etesian.antennaDiodeMaxWL", 0 )->asInt())
|
||||
{
|
||||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
|
@ -159,6 +160,14 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_antennaGateMaxWL and not _antennaDiodeMaxWL) {
|
||||
_antennaDiodeMaxWL = _antennaGateMaxWL;
|
||||
cerr << Warning( "Anabatic::Configuration(): \"etesian.antennaGateMaxWL\" is defined but not \"etesian.antennaDiodeMaxWL\".\n"
|
||||
" Setting both to %s"
|
||||
, DbU::getValueString(_antennaGateMaxWL).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,9 +190,10 @@ namespace Anabatic {
|
|||
, _edgeCostK (other._edgeCostK)
|
||||
, _edgeHInc (other._edgeHInc)
|
||||
, _edgeHScaling (other._edgeHScaling)
|
||||
, _globalIterations(other._globalIterations)
|
||||
, _globalIterations (other._globalIterations)
|
||||
, _diodeName (other._diodeName)
|
||||
, _antennaMaxWL (other._antennaMaxWL)
|
||||
, _antennaGateMaxWL (other._antennaGateMaxWL)
|
||||
, _antennaDiodeMaxWL(other._antennaDiodeMaxWL)
|
||||
{
|
||||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
|
@ -592,7 +602,8 @@ namespace Anabatic {
|
|||
record->add( getSlot( "_edgeHInc" , _edgeHInc ) );
|
||||
record->add( getSlot( "_edgeHScaling" , _edgeHScaling ) );
|
||||
record->add( getSlot( "_globalIterations", _globalIterations ) );
|
||||
record->add( DbU::getValueSlot( "_antennaMaxWL", &_antennaMaxWL ) );
|
||||
record->add( DbU::getValueSlot( "_antennaGateMaxWL" , &_antennaGateMaxWL ) );
|
||||
record->add( DbU::getValueSlot( "_antennaDiodeMaxWL", &_antennaDiodeMaxWL ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
|
|
@ -1459,8 +1459,8 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
DbU::Unit Dijkstra::getAntennaMaxWL () const
|
||||
{ return _anabatic->getAntennaMaxWL(); }
|
||||
DbU::Unit Dijkstra::getAntennaGateMaxWL () const
|
||||
{ return _anabatic->getAntennaGateMaxWL(); }
|
||||
|
||||
|
||||
Point Dijkstra::_getPonderedPoint() const
|
||||
|
@ -2330,7 +2330,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
if (gWL > getAntennaMaxWL()) {
|
||||
if (gWL > getAntennaGateMaxWL()) {
|
||||
cdebug_log(113,0) << "| \"" << _net->getName() << "\" may have antenna effect, "
|
||||
<< DbU::getValueString(gWL)
|
||||
<< endl;
|
||||
|
|
|
@ -248,7 +248,8 @@ namespace Anabatic {
|
|||
inline bool doDestroyBaseContact () const;
|
||||
inline bool doDestroyBaseSegment () const;
|
||||
inline bool doDestroyTool () const;
|
||||
inline DbU::Unit getAntennaMaxWL () const;
|
||||
inline DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
inline DbU::Unit getGlobalThreshold () const;
|
||||
inline float getSaturateRatio () const;
|
||||
inline size_t getSaturateRp () const;
|
||||
|
@ -376,7 +377,8 @@ namespace Anabatic {
|
|||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
||||
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaMaxWL () const { return getConfiguration()->getAntennaMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return getConfiguration()->getAntennaDiodeMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
|
||||
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
|
||||
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
|
||||
|
|
|
@ -116,7 +116,8 @@ namespace Anabatic {
|
|||
float getSaturateRatio () const;
|
||||
size_t getSaturateRp () const;
|
||||
inline std::string getDiodeName () const;
|
||||
inline DbU::Unit getAntennaMaxWL () const;
|
||||
inline DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
DbU::Unit getGlobalThreshold () const;
|
||||
void setAllowedDepth ( size_t );
|
||||
void setSaturateRatio ( float );
|
||||
|
@ -160,7 +161,8 @@ namespace Anabatic {
|
|||
float _edgeHScaling;
|
||||
int _globalIterations;
|
||||
std::string _diodeName;
|
||||
DbU::Unit _antennaMaxWL;
|
||||
DbU::Unit _antennaGateMaxWL;
|
||||
DbU::Unit _antennaDiodeMaxWL;
|
||||
private:
|
||||
Configuration& operator= ( const Configuration& ) = delete;
|
||||
void _setTopRoutingLayer ( Name name );
|
||||
|
@ -189,7 +191,8 @@ namespace Anabatic {
|
|||
inline DbU::Unit Configuration::getDContactWidth () const { return getWireWidth ( getDContactDepth() ); }
|
||||
inline DbU::Unit Configuration::getDContactPitch () const { return getPitch ( getDContactDepth(), Flags::NoFlags ); }
|
||||
inline std::string Configuration::getDiodeName () const { return _diodeName; }
|
||||
inline DbU::Unit Configuration::getAntennaMaxWL () const { return _antennaMaxWL; }
|
||||
inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; }
|
||||
inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -522,7 +522,7 @@ namespace Anabatic {
|
|||
inline bool isSourceVertex ( Vertex* ) const;
|
||||
inline Net* getNet () const;
|
||||
inline bool isTargetVertex ( Vertex* ) const;
|
||||
DbU::Unit getAntennaMaxWL () const;
|
||||
DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getSearchAreaHalo () const;
|
||||
template<typename DistanceT>
|
||||
inline DistanceT* setDistance ( DistanceT );
|
||||
|
|
Loading…
Reference in New Issue