More tuning for ARMv2a (95% success, 38/40). Bugs in core2chip.

* Change: In Anabatic::GCell::updateDensity(), all non-passthrough wires
    now have a cost of 0.5 instead of 0.33 for locals.
* Change: In Manipulator::canMoveUp(), increase the "reserve" amount to
    1.0 for "far from terminal" wires (rpDistance > 2).
* Change: In NegociateWindow::NegociateOverlapCost(), always sets "AtRipupLimit"
    when the overlapping segment is nearing it's maximum ripup limit.
    (different detection for non-preferred and regular)
* Change: In SegmentFsm::_slackenStrap(), call avoidBlockage() if it is
    overlapping a blockage *or* a segment at it's ripup limit. I hope I
    didn't create an infinite loop here.
* Bug: In cumulus/plugins/PadsCorona.py, CoreWire._computeCoreLayers(),
    the big contact between symbolic and real was badly computed for
    east/west (was using width instead of height, bummer!).
      In Corona._createCoreWire(), completly screwed computation of the
    side gap, was using a badly initialized value of the "bb" variable.
* Bug: In cumulus/plugins/Chip.py, the computation of the minimal size
    for the corona was wrong, do *not* add the size of the pads and
    multiply by two as it is done by "inflate". This was forcing the user
    to create way to large chips for a given core size.
This commit is contained in:
Jean-Paul Chaput 2019-09-25 18:35:03 +02:00
parent d7931391c0
commit 2bd18313d1
7 changed files with 104 additions and 65 deletions

View File

@ -1499,7 +1499,8 @@ namespace Anabatic {
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0;
for ( ; isegment != processeds.end(); ++isegment ) {
_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
//_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
_feedthroughs[depth] += 0.50;
localCounts [depth] += 1.0;
if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0;

View File

@ -126,8 +126,8 @@ class PlaceRoute ( object ):
if not self.conf.useClockTree: self.railsNb -= 1
innerBb = Box( self.conf.coreSize )
innerBb.inflate( (railsNb * vRailWidth + (railsNb+1) * vRailSpace + self.conf.getSliceHeight()) * 2
, (railsNb * hRailWidth + (railsNb+1) * hRailSpace + self.conf.getSliceHeight()) * 2 )
innerBb.inflate( railsNb * vRailWidth + (railsNb+1) * vRailSpace
, railsNb * hRailWidth + (railsNb+1) * hRailSpace )
coronaAb = self.conf.corona.getAbutmentBox()
if innerBb.getWidth() > coronaAb.getWidth():

View File

@ -38,6 +38,7 @@ from Hurricane import RoutingPad
from Hurricane import Instance
import CRL
from CRL import RoutingLayerGauge
import helpers
from helpers import trace
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
@ -661,6 +662,9 @@ class CoreWire ( object ):
rg = self.conf.gaugeConf.routingGauge
mask = self.padSegment.getLayer().getMask()
trace( 550, ',+', '\tCoreWire._computeCoreLayers()\n' )
trace( 550, '\tbbSegment: %s\n' % (self.bbSegment) )
self.symSegmentLayer = None
for layerGauge in rg.getLayerGauges():
if layerGauge.getDepth() > self.conf.gaugeConf.topLayerDepth: break
@ -683,28 +687,35 @@ class CoreWire ( object ):
self.symSegmentLayer = rg.getLayerGauge( depth+1 ).getLayer()
self.symContactLayer = rg.getContactLayer( depth )
self.symContactSize = ( self.bbSegment.getWidth(), self.bbSegment.getWidth() )
if self.side & (chip.West|chip.East):
self.symContactSize = ( self.bbSegment.getHeight(), self.bbSegment.getHeight() )
else:
self.symContactSize = ( self.bbSegment.getWidth(), self.bbSegment.getWidth() )
contactMinSize = 2*self.symContactLayer.getEnclosure( self.symSegmentLayer.getBasicLayer()
, Layer.EnclosureH|Layer.EnclosureV ) \
+ self.symContactLayer.getMinimalSize()
arrayWidth = (self.bbSegment.getWidth() - contactMinSize) / CoreWire.viaPitch
trace( 550, '\tcontactMinSize: %sl, width: %sl, arrayWidth: %d\n'
% (DbU.toLambda(contactMinSize),DbU.toLambda(self.bbSegment.getWidth()),arrayWidth) )
if arrayWidth < 0: arrayWidth = 0
if arrayWidth < 3:
arrayWidth = self.symContactSize[0]
arrayCount = (arrayWidth - contactMinSize) / CoreWire.viaPitch
trace( 550, '\tCoreWire.viaPitch: %sl\n' % (DbU.toLambda(CoreWire.viaPitch)) )
trace( 550, '\tcontactMinSize: %sl, arrayWidth: %sl, arrayCount: %d\n'
% (DbU.toLambda(contactMinSize),DbU.toLambda(arrayWidth),arrayCount) )
if arrayCount < 0: arrayCount = 0
if arrayCount < 3:
if self.side & (chip.North|chip.South):
self.arraySize = ( arrayWidth+1, 2 )
self.arraySize = ( arrayCount+1, 2 )
else:
self.arraySize = ( 2, arrayWidth+1 )
self.arraySize = ( 2, arrayCount+1 )
trace( 550, '\tarraySize = (%d,%d)\n' % (self.arraySize[0], self.arraySize[1]) )
trace( 550, ',-' )
return
raise ErrorMessage( 1, 'CoreWire._computeCoreLayers(): Layer of IO pad segment "%s" is not in routing gauge.' \
% self.chipNet.getName() )
trace( 550, ',-' )
return
@ -1086,10 +1097,11 @@ class Corona ( object ):
for component in padNet.getExternalComponents():
if isinstance(component,Segment) or isinstance(component,Contact):
bb = component.getBoundingBox()
padInstance.getTransformation().applyOn( bb )
if bb.intersect(innerBb):
trace( 550, '\tTerm comp:%s bb:%s\n' % (component,bb) )
lg = rg.getLayerGauge( component.getLayer() )
depth = lg.getDepth()
if depth > self.conf.gaugeConf.topLayerDepth: continue
@ -1118,21 +1130,26 @@ class Corona ( object ):
segments = vsegments[ min(vsegments.keys()) ]
elif len(hsegments):
segments = hsegments[ min(hsegments.keys()) ]
gapWidth = bb.getWidth()
trace( 550, '\tNorth/South but RDir H, gapWidth: %s\n' % DbU.getValueString(gapWidth) )
else:
if len(hsegments):
inPreferredDir = True
segments = hsegments[ min(hsegments.keys()) ]
elif len(vsegments):
segments = vsegments[ min(vsegments.keys()) ]
gapWidth = bb.getWidth()
trace( 550, '\tEast/West but RDir V, gapWidth: %s\n' % DbU.getValueString(gapWidth) )
coreWires = []
if segments:
for segment, bb in segments:
side.updateGap ( gapWidth )
if not inPreferredDir:
if side.type == chip.North or side.type == chip.South:
trace( 550, '\tNorth/South "%s" but RDir H, gapWidth: %s\n'
% (chipIntNet.getName(),DbU.getValueString(bb.getWidth()) ) )
side.updateGap( bb.getWidth() )
else:
trace( 550, '\tEast/West "%s" but RDir V, gapWidth: %s\n'
% (chipIntNet.getName(),DbU.getValueString(bb.getHeight())) )
side.updateGap( bb.getHeight() )
side.addCoreWire( CoreWire( self, chipIntNet, segment, bb, side.type, inPreferredDir, count ) )
count += 1
else:

View File

@ -1180,6 +1180,10 @@ namespace Katana {
kflags |= (flags & AllowTerminalMoveUp) ? Flags::AllowTerminal : Flags::NoFlags;
kflags |= (flags & IgnoreContacts ) ? Flags::IgnoreContacts : Flags::NoFlags;
//float reserve = 1.0;
float reserve = 0.5;
if (_segment->base() and (_segment->base()->getRpDistance() > 2)) reserve = 1.0;
if (_segment->isFixed()) return false;
if (not (flags & AllowLocalMoveUp)) {
if (_segment->isLocal()) {
@ -1189,7 +1193,7 @@ namespace Katana {
if (not (flags & AllowShortPivotUp)) return false;
if (not _segment->canPivotUp(1.0,(kflags & ~Flags::IgnoreContacts))) return false;
}
if (not _segment->canMoveUp(0.5,kflags)) return false;
if (not _segment->canMoveUp(reserve,kflags)) return false;
}
} else {
if (not _segment->canMoveUp(0.5,kflags)) return false;
@ -1701,7 +1705,6 @@ namespace Katana {
isSourceTerminal = false;
}
TrackElement* perpandicular = _event->getPerpandiculars()[0];
DataNegociate* data = perpandicular->getDataNegociate();

View File

@ -20,6 +20,7 @@
#include <iomanip>
#include "hurricane/Breakpoint.h"
#include "hurricane/DebugSession.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Warning.h"
#include "hurricane/Bug.h"
#include "hurricane/RoutingPad.h"
@ -89,13 +90,21 @@ namespace {
AutoSegment* refBase = refSegment->base();
AutoSegment* base = segment->base();
if ( base and refBase and refData
and ( base->getRpDistance() == 0)
and (refBase->getRpDistance() > 0)
and (refData->getState() > DataNegociate::RipupPerpandiculars)
and ( data->getState() == DataNegociate::RipupPerpandiculars)
and ( data->getRipupCount() > 4)) {
cost.setAtRipupLimit();
if (base and refBase and refData) {
if ( ( base->getRpDistance() == 0)
and (refBase->getRpDistance() > 0)
and (refData->getState() > DataNegociate::RipupPerpandiculars)
and ( data->getState() == DataNegociate::RipupPerpandiculars)
and ( data->getRipupCount() > 4)) {
cost.setAtRipupLimit();
}
if ( refSegment->isNonPref()
and segment->isUnbreakable()
and (data->getState() >= DataNegociate::Minimize)
and (data->getStateCount() >= 2) ) {
cost.setAtRipupLimit();
}
}
cost.mergeRipupCount( data->getRipupCount() );
@ -107,6 +116,10 @@ namespace {
}
}
if (data->getState() == DataNegociate::MaximumSlack) {
cost.setAtRipupLimit();
}
if (segment->isGlobal()) {
cost.setOverlapGlobal();
if ( (cost.getFlags() & TrackCost::LocalAndTopDepth)
@ -229,6 +242,7 @@ namespace Katana {
using Hurricane::tab;
using Hurricane::ForEachIterator;
using Hurricane::DebugSession;
using Hurricane::UpdateSession;
using CRL::Histogram;
using CRL::addMeasure;
using Anabatic::AutoContact;
@ -592,6 +606,14 @@ namespace Katana {
event->process( _eventQueue, _eventHistory, _eventLoop );
count++;
// if (event->getSegment()->getNet()->getId() == 239546) {
// UpdateSession::close();
// ostringstream message;
// message << "After processing an event from Net id:239546\n" << event;
// Breakpoint::stop( 0, message.str() );
// UpdateSession::open();
// }
//if (count and not (count % 500)) {
// _pack( count, false );
//}

View File

@ -1208,41 +1208,43 @@ namespace Katana {
uint32_t nextState = data->getState();
Manipulator manipulator ( segment, *this );
switch ( data->getState() ) {
case DataNegociate::RipupPerpandiculars:
nextState = DataNegociate::Minimize;
if (segment->isNonPref() and getCost(0)->isBlockage()) {
cdebug_log(159,0) << "Non-preferred conflicts with a blockage." << endl;
success = manipulator.avoidBlockage();
if (segment->isNonPref() and (getCost(0)->isBlockage() or getCost(0)->isAtRipupLimit())) {
cdebug_log(159,0) << "Non-preferred conflicts with a blockage or other's at ripup limit." << endl;
success = manipulator.avoidBlockage();
}
if (not success) {
switch ( data->getState() ) {
case DataNegociate::RipupPerpandiculars:
nextState = DataNegociate::Minimize;
success = manipulator.ripupPerpandiculars();
if (success) break;
}
success = manipulator.ripupPerpandiculars();
if (success) break;
case DataNegociate::Minimize:
if (data->getStateCount() >= 2) {
nextState = DataNegociate::Slacken;
}
success = manipulator.minimize();
if (success) break;
case DataNegociate::Dogleg:
case DataNegociate::Slacken:
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
nextState = DataNegociate::LocalVsGlobal;
case DataNegociate::Minimize:
if (data->getStateCount() >= 2) {
nextState = DataNegociate::Slacken;
}
success = manipulator.minimize();
if (success) break;
case DataNegociate::Dogleg:
case DataNegociate::Slacken:
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
nextState = DataNegociate::LocalVsGlobal;
break;
}
case DataNegociate::LocalVsGlobal:
if (segment->isUnbreakable()) {
nextState = DataNegociate::MaximumSlack;
success = true;
break;
}
case DataNegociate::ConflictSolveByHistory:
case DataNegociate::ConflictSolveByPlaceds:
case DataNegociate::MoveUp:
case DataNegociate::MaximumSlack:
case DataNegociate::Unimplemented:
nextState = DataNegociate::Unimplemented;
break;
}
case DataNegociate::LocalVsGlobal:
if (segment->isUnbreakable()) {
nextState = DataNegociate::MaximumSlack;
success = true;
break;
}
case DataNegociate::ConflictSolveByHistory:
case DataNegociate::ConflictSolveByPlaceds:
case DataNegociate::MoveUp:
case DataNegociate::MaximumSlack:
case DataNegociate::Unimplemented:
nextState = DataNegociate::Unimplemented;
break;
}
}
if (not success and (nextState != DataNegociate::Unimplemented))

View File

@ -161,7 +161,6 @@ namespace Katana {
size_t begin;
getBeginIndex( position, begin, state );
cdebug_log(159,0) << " getSegment(position): begin:" << begin << endl;
if (state & (BeginIsTrackMin|EndIsTrackMax)) return NULL;
return getSegment(begin);
@ -239,26 +238,21 @@ namespace Katana {
// I guess this has been written for the case of overlapping segments from the same
// net, we find the first one of the overlapped sets. But what if they are not overlapping
// but still from the same net?
cdebug_log(159,0) << " begin:" << begin << endl;
size_t sameNetDelta = 0;
if (begin < _segments.size()) {
for ( ; (begin > 0) and (_segments[begin-1]->getNet() == _segments[begin]->getNet())
; --begin, ++sameNetDelta );
}
cdebug_log(159,0) << " begin:" << begin << endl;
state = 0;
if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) {
state = BeforeFirstElement;
} else {
if (begin and not sameNetDelta) begin -= 1;
cdebug_log(159,0) << " begin:" << begin << endl;
size_t usedBegin = begin;
Interval usedInterval = getOccupiedInterval( usedBegin );
cdebug_log(159,0) << " position:" << DbU::getValueString(position)
<< " " << usedInterval << endl;
if (position < usedInterval.getVMax())
state = InsideElement;
else