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:
Jean-Paul Chaput 2021-12-11 19:51:24 +01:00
parent ba2a74e35d
commit 2ca9e162ef
5 changed files with 77 additions and 52 deletions

View File

@ -615,6 +615,7 @@ namespace Anabatic {
}
}
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
size_t errorCount = 0;
ostringstream errors;
errors << "AnabaticEngine::checkPlacement():\n";
@ -626,55 +627,62 @@ namespace Anabatic {
ostringstream pinError;
Point pinCenter = rp->getCenter();
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
if (pin->getLayer() != getConfiguration()->getDVerticalLayer()) {
pinError << " Should be in vertical routing layer, "
<< "pin:" << pin->getLayer()->getName()
<< " vs gauge:" << getConfiguration()->getDVerticalLayer()->getName()
<< "\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;
}
}
RoutingLayerGauge* lg = rg->getLayerGauge( pin->getLayer() );
if (not lg) {
pinError << " Layer not in the routing gauge, "
<< "pin:" << pin->getLayer()->getName()
<< "\n";
valid = false;
++errorCount;
} else {
Point pinCenter = rp->getCenter();
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 ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
if (pin->getLayer() != getConfiguration()->getDHorizontalLayer()) {
pinError << " Should be in horizontal routing layer, "
<< "pin:" << pin->getLayer()->getName()
<< " vs gauge:" << getConfiguration()->getDHorizontalLayer()->getName()
<< "\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 ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
if (not lg->isHorizontal()) {
pinError << " Should be in horizontal routing layer, "
<< "pin:" << pin->getLayer()->getName()
<< " vs gauge:" << lg->getLayer()->getName()
<< "\n";
valid = false;
++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 (not pinError.str().empty()) {
errors << "On " << pin << "\n" << pinError.str();
if (not pinError.str().empty()) {
errors << "On " << pin << "\n" << pinError.str();
}
}
}
}

View File

@ -2770,10 +2770,23 @@ namespace Anabatic {
, Segment* hurricaneSegment
)
{
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
const Layer* horizontalLayer = Session::getDHorizontalLayer();
DbU::Unit horizontalWidth = Session::getDHorizontalWidth();
const Layer* verticalLayer = Session::getDVerticalLayer();
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() );
if (wPitch > 1) {
@ -2788,9 +2801,7 @@ namespace Anabatic {
bool reattachSource = false;
bool reattachTarget = false;
AutoSegment* segment;
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
AutoSegment* segment = NULL;
AutoContact* reference = NULL;
cdebug_log(149,0) << "Source:" << source << endl;

View File

@ -170,7 +170,8 @@ namespace Anabatic {
sourceProtect->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 );
getRpLookup().insert( make_pair(rp,segment) );

View File

@ -2037,7 +2037,7 @@ namespace Katabatic {
void KatabaticEngine::_loadGrByNet ()
{
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();
Session::open( this );

View File

@ -334,6 +334,11 @@ namespace Katana {
Interval fixedSpan;
Interval blockageSpan;
if (not refTrack) {
string message = "NULL refTrack for " + getString(autoSegment);
Breakpoint::stop( 0, message );
}
if (refTrack->getAxis() != autoSegment->getAxis()) {
trackSpan = 2;
refTrack = plane->getTrackByPosition( autoSegment->getAxis(), Constant::Inferior );