Allow the detailed routing to be build from non-bottom P&R layers.
* New: In Anabatic::AutoSegment::create(), allow the created segment to be in any supported routing layer, and not only the bottom H & V. Modifications impact the *two* overload of the function. * Change: In Anabatic::NetBuilderHV::doRp_AutoContacts(), for punctual METAL1, the protection has to be in METAL2. Bump the layer depth to correctly use the updated verstion of AutoSegment::create(). * Change: In AnabaticEngine::checkPlacement(), for the Pin, check that it's layer is in the routing gauge before anything else. * New: In Katana::NegociateWindow::createTrackSegment(), if the track nearest the segment axis (refTrack) do not exists, call a breakpoint just before crashing.
This commit is contained in:
parent
ba2a74e35d
commit
2ca9e162ef
|
@ -615,6 +615,7 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
|
||||||
size_t errorCount = 0;
|
size_t errorCount = 0;
|
||||||
ostringstream errors;
|
ostringstream errors;
|
||||||
errors << "AnabaticEngine::checkPlacement():\n";
|
errors << "AnabaticEngine::checkPlacement():\n";
|
||||||
|
@ -626,55 +627,62 @@ namespace Anabatic {
|
||||||
|
|
||||||
ostringstream pinError;
|
ostringstream pinError;
|
||||||
|
|
||||||
Point pinCenter = rp->getCenter();
|
RoutingLayerGauge* lg = rg->getLayerGauge( pin->getLayer() );
|
||||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
|
if (not lg) {
|
||||||
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
|
pinError << " Layer not in the routing gauge, "
|
||||||
if (pin->getLayer() != getConfiguration()->getDVerticalLayer()) {
|
<< "pin:" << pin->getLayer()->getName()
|
||||||
pinError << " Should be in vertical routing layer, "
|
<< "\n";
|
||||||
<< "pin:" << pin->getLayer()->getName()
|
valid = false;
|
||||||
<< " vs gauge:" << getConfiguration()->getDVerticalLayer()->getName()
|
++errorCount;
|
||||||
<< "\n";
|
} else {
|
||||||
valid = false;
|
Point pinCenter = rp->getCenter();
|
||||||
++errorCount;
|
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
|
||||||
|
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
|
||||||
|
if (not lg->isVertical()) {
|
||||||
|
pinError << " Should be in vertical routing layer, "
|
||||||
|
<< "pin:" << pin->getLayer()->getName()
|
||||||
|
<< " vs gauge:" << lg->getLayer()->getName()
|
||||||
|
<< "\n";
|
||||||
|
valid = false;
|
||||||
|
++errorCount;
|
||||||
|
}
|
||||||
|
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin() - lg->getOffset())
|
||||||
|
% lg->getPitch()) {
|
||||||
|
pinError << " Misaligned, "
|
||||||
|
<< "pin:" << DbU::getValueString(pinCenter.getX())
|
||||||
|
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
|
||||||
|
<< ", offset:" << DbU::getValueString(lg->getOffset())
|
||||||
|
<< "\n";
|
||||||
|
valid = false;
|
||||||
|
++errorCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin()
|
|
||||||
- getConfiguration()->getDVerticalOffset())
|
|
||||||
% getConfiguration()->getDVerticalPitch()) {
|
|
||||||
pinError << " Misaligned, "
|
|
||||||
<< "pin:" << DbU::getValueString(pinCenter.getX())
|
|
||||||
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDVerticalPitch ())
|
|
||||||
<< ", offset:" << DbU::getValueString(getConfiguration()->getDVerticalOffset())
|
|
||||||
<< "\n";
|
|
||||||
valid = false;
|
|
||||||
++errorCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
|
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
|
||||||
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
|
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
|
||||||
if (pin->getLayer() != getConfiguration()->getDHorizontalLayer()) {
|
if (not lg->isHorizontal()) {
|
||||||
pinError << " Should be in horizontal routing layer, "
|
pinError << " Should be in horizontal routing layer, "
|
||||||
<< "pin:" << pin->getLayer()->getName()
|
<< "pin:" << pin->getLayer()->getName()
|
||||||
<< " vs gauge:" << getConfiguration()->getDHorizontalLayer()->getName()
|
<< " vs gauge:" << lg->getLayer()->getName()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
valid = false;
|
valid = false;
|
||||||
++errorCount;
|
++errorCount;
|
||||||
|
}
|
||||||
|
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin() - lg->getOffset())
|
||||||
|
% lg->getPitch()) {
|
||||||
|
pinError << " Misaligned, "
|
||||||
|
<< "pin:" << DbU::getValueString(pinCenter.getY())
|
||||||
|
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
|
||||||
|
<< ", offset:" << DbU::getValueString(lg->getOffset())
|
||||||
|
<< "\n";
|
||||||
|
valid = false;
|
||||||
|
++errorCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin()
|
|
||||||
- getConfiguration()->getDHorizontalOffset())
|
|
||||||
% getConfiguration()->getDHorizontalPitch()) {
|
|
||||||
pinError << " Misaligned, "
|
|
||||||
<< "pin:" << DbU::getValueString(pinCenter.getY())
|
|
||||||
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDHorizontalPitch ())
|
|
||||||
<< ", offset:" << DbU::getValueString(getConfiguration()->getDHorizontalOffset())
|
|
||||||
<< "\n";
|
|
||||||
valid = false;
|
|
||||||
++errorCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not pinError.str().empty()) {
|
if (not pinError.str().empty()) {
|
||||||
errors << "On " << pin << "\n" << pinError.str();
|
errors << "On " << pin << "\n" << pinError.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2770,10 +2770,23 @@ namespace Anabatic {
|
||||||
, Segment* hurricaneSegment
|
, Segment* hurricaneSegment
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
|
||||||
|
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
|
||||||
|
|
||||||
const Layer* horizontalLayer = Session::getDHorizontalLayer();
|
const Layer* horizontalLayer = Session::getDHorizontalLayer();
|
||||||
DbU::Unit horizontalWidth = Session::getDHorizontalWidth();
|
DbU::Unit horizontalWidth = Session::getDHorizontalWidth();
|
||||||
const Layer* verticalLayer = Session::getDVerticalLayer();
|
const Layer* verticalLayer = Session::getDVerticalLayer();
|
||||||
DbU::Unit verticalWidth = Session::getDVerticalWidth();
|
DbU::Unit verticalWidth = Session::getDVerticalWidth();
|
||||||
|
if (not Session::getAnabatic()->getConfiguration()->isGMetal(hurricaneSegment->getLayer())) {
|
||||||
|
size_t depth = Session::getAnabatic()->getConfiguration()->getLayerDepth( hurricaneSegment->getLayer() );
|
||||||
|
if (depth > 2) {
|
||||||
|
horizontalLayer = verticalLayer = hurricaneSegment->getLayer();
|
||||||
|
horizontalWidth = Session::getAnabatic()->getConfiguration()->getWireWidth( depth );
|
||||||
|
verticalWidth = Session::getAnabatic()->getConfiguration()->getPWireWidth( depth );
|
||||||
|
if (vertical)
|
||||||
|
std::swap( horizontalWidth, verticalWidth );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
|
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
|
||||||
if (wPitch > 1) {
|
if (wPitch > 1) {
|
||||||
|
@ -2788,9 +2801,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
bool reattachSource = false;
|
bool reattachSource = false;
|
||||||
bool reattachTarget = false;
|
bool reattachTarget = false;
|
||||||
AutoSegment* segment;
|
AutoSegment* segment = NULL;
|
||||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
|
|
||||||
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
|
|
||||||
AutoContact* reference = NULL;
|
AutoContact* reference = NULL;
|
||||||
|
|
||||||
cdebug_log(149,0) << "Source:" << source << endl;
|
cdebug_log(149,0) << "Source:" << source << endl;
|
||||||
|
|
|
@ -170,7 +170,8 @@ namespace Anabatic {
|
||||||
sourceProtect->setFlags( CntFixed );
|
sourceProtect->setFlags( CntFixed );
|
||||||
targetProtect->setFlags( CntFixed );
|
targetProtect->setFlags( CntFixed );
|
||||||
|
|
||||||
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
|
if (rpDepth == 0) rpDepth = 1;
|
||||||
|
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction, rpDepth );
|
||||||
segment->setFlags( AutoSegment::SegFixed );
|
segment->setFlags( AutoSegment::SegFixed );
|
||||||
|
|
||||||
getRpLookup().insert( make_pair(rp,segment) );
|
getRpLookup().insert( make_pair(rp,segment) );
|
||||||
|
|
|
@ -2037,7 +2037,7 @@ namespace Katabatic {
|
||||||
void KatabaticEngine::_loadGrByNet ()
|
void KatabaticEngine::_loadGrByNet ()
|
||||||
{
|
{
|
||||||
cmess1 << " o Loading Nets global routing from Knik." << endl;
|
cmess1 << " o Loading Nets global routing from Knik." << endl;
|
||||||
cmess1 << Dots::asDouble(" - Saturation",getMeasure<double>("Sat.")) << endl;
|
cmess1 << Dots::asDouble(" - Saturation",*getMeasure<double>("Sat.")) << endl;
|
||||||
|
|
||||||
startMeasures();
|
startMeasures();
|
||||||
Session::open( this );
|
Session::open( this );
|
||||||
|
|
|
@ -334,6 +334,11 @@ namespace Katana {
|
||||||
Interval fixedSpan;
|
Interval fixedSpan;
|
||||||
Interval blockageSpan;
|
Interval blockageSpan;
|
||||||
|
|
||||||
|
if (not refTrack) {
|
||||||
|
string message = "NULL refTrack for " + getString(autoSegment);
|
||||||
|
Breakpoint::stop( 0, message );
|
||||||
|
}
|
||||||
|
|
||||||
if (refTrack->getAxis() != autoSegment->getAxis()) {
|
if (refTrack->getAxis() != autoSegment->getAxis()) {
|
||||||
trackSpan = 2;
|
trackSpan = 2;
|
||||||
refTrack = plane->getTrackByPosition( autoSegment->getAxis(), Constant::Inferior );
|
refTrack = plane->getTrackByPosition( autoSegment->getAxis(), Constant::Inferior );
|
||||||
|
|
Loading…
Reference in New Issue