Compare commits

...

12 Commits

Author SHA1 Message Date
Jean-Paul Chaput 1569e2807e In CRL::GdsParser, GDS layers indexes up to 1024, just in case. 2021-06-12 17:52:29 +02:00
Jean-Paul Chaput f3ccf31e48 Fix incomplete GDS layer table in GdsParser.
* Bug: In CRL::GdsParser(), the table of GDS layer was limited to 64,
   which is the maximum, according to the reference. But it is no
   longer true. Extend to 256.
     This was leading to GDS files missing some layers.
2021-06-12 16:29:08 +02:00
Jean-Paul Chaput 3bd1d56582 Fix last DRC incorrect case in TrackSegment::isMiddleStack().
* Bug: In TrackSegment::isMiddleStack(), formerly, all global segments
    where discarted. But in the routing repair stage, segments can go
    *outside* their GCell boundaries, allowing globals to became of
    null length.
       Hence, for global, we now also check the wirelength.
2021-06-12 16:21:10 +02:00
Jean-Paul Chaput f9e4daace9 Comment out debug information in Track::repair(). 2021-06-12 16:17:03 +02:00
Jean-Paul Chaput ffd6f571b5 No longer connect the root of HTrees with straigh lines, use the router.
* Change: In cumulus/plugins.chip.chip.doConnectCore(), do not use the
    feature of the HTree to connect the root buffer straight to the
    corona pin. It prevents the router to insert a diode when those
    wires are too long. So let the standard router manage them.
      Should add diode insertions in HTree.connectHTrees() later.
2021-06-12 11:49:07 +02:00
Jean-Paul Chaput 1733b5142a Fix bad index in Track::repair().
* Bug: In Track::repair(), when a same net gap has been found and closed,
    we display a warning. We display the two segments fused, but when it's
    the two first, we must not use index "i-1" (with i=0) ...
2021-06-12 11:42:53 +02:00
Jean-Paul Chaput ebe8ea64c6 Freeze version of RapidJSON to build under SL7.
* Change: In bootstrap/socInstaller.py, freeze the version of RapidJSON
    to commmit #b1a4d91 as later ones have problems building their doc
    under SL7.
2021-06-11 11:47:35 +02:00
Jean-Paul Chaput 4e7dbee831 Fix HTree to corona's edge wiring in horizontal direction.
* Bug: In cumulus/plugins.chip.powerplane.Builder._connectHTree(),
    when building the stacked VIAs over the corona Pin and the
    root buffer RoutingPad, pass the GaugeConf.HAccess flag so the
    stack stops at METAL4 (top horizontal layer).
      Before we where also adding a VIA up to METAL5 which was unused
    and caused a minimal area violation.
2021-06-11 11:47:02 +02:00
Jean-Paul Chaput 68812fa0ca Fix same net gap between the two last elements of a Track.
* Bug: In Track::repair(), the same net gaps between the last and before
    last track elements where overlooked. Leading to very rare DRC
    violations.
2021-06-11 11:46:37 +02:00
Jean-Paul Chaput 7c8d47a2d1 More generic criterion for finding under minimum area segments.
* Change: In AutoSegment::isMiddleStack(), after checking for obvious
    non-candidates, relies on axis-to-axis wirelength instead of topological
    criterions. We will not be able to account all the topologies that
    may cause problem. So consider every segment whose length is below
    one perpandicular pitch.
2021-06-11 11:46:13 +02:00
Jean-Paul Chaput 9c153699be Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2021-06-10 15:29:31 +02:00
Jean-Paul Chaput 79858840fc In NetBuilderHV::_do_xG_1M1(), less rigid topology for straight vertical. 2021-06-10 15:29:00 +02:00
7 changed files with 115 additions and 54 deletions

View File

@ -1615,7 +1615,12 @@ namespace Anabatic {
bool AutoSegment::isMiddleStack () const
{
cdebug_log(149,0) << "AutoSegment::isMiddleStack() - " << this << endl;
if (isGlobal() or isNonPref()) return false;
if (isNonPref()) return false;
if (isGlobal()) {
if (getLength() > getPPitch()) return false;
cdebug_log(149,0) << "| Considering this global anyway because it is too short. " << endl;
}
AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget();
if (not source or not target) {
@ -1652,11 +1657,11 @@ namespace Anabatic {
}
}
if ((source->isHTee() or target->isHTee()) and isHorizontal()) {
cdebug_log(149,0) << "| false, S/T HTee and horizontal. " << this << endl;
return false;
} else if ((source->isVTee() or target->isVTee()) and isVertical()) {
cdebug_log(149,0) << "| false, S/T VTee and vertical. " << this << endl;
DbU::Unit sourceAxis = 0;
DbU::Unit targetAxis = 0;
getEndAxes( sourceAxis, targetAxis );
if ((targetAxis - sourceAxis) >= getPPitch()) {
cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl;
return false;
}
cdebug_log(149,0) << " Middle stack or terminal bound." << endl;

View File

@ -1258,9 +1258,12 @@ namespace Anabatic {
if (getConnexity().fields.globals == 2) {
if (north() and south()) {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Horizontal );
setBothCornerContacts( contact2 );
contact1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Horizontal );
setNorthEastContact( contact1 );
setSouthWestContact( contact2 );
} else if (east() and west()) {
// AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
// AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );

View File

@ -593,8 +593,8 @@ try:
for gitSupport in gitSupports:
if conf.rmSource: gitSupport.removeLocalRepo()
gitSupport.clone()
#if gitSupport.url.endswith('rapidjson'):
# gitSupport.checkout( 'a1c4f32' )
if gitSupport.url.endswith('rapidjson'):
gitSupport.checkout( 'b1a4d91' )
if conf.doAlliance:
if conf.rmSource: gitAlliance.removeLocalRepo()

View File

@ -505,7 +505,7 @@ namespace {
for ( ; _count<_length ; ++_count ) {
_stream->get( c );
sprintf( _buffer, "0x%02x", c );
cdebug_log(101,0) << setw(6) << hex << _offset++ << " | " << _buffer << endl;
cdebug_log(101,0) << tsetw(6) << hex << _offset++ << " | " << _buffer << endl;
}
if (showError) {
cdebug_log(101,0) << Error( "GdsRecord type %s unsupported.", toStrType(_type).c_str() ) << endl;
@ -723,10 +723,10 @@ namespace {
void GdsStream::_staticInit ()
{
_gdsLayerTable = vector<const Layer*>( 64, NULL );
_gdsLayerTable = vector<const Layer*>( 1024, NULL );
for ( const BasicLayer* layer : DataBase::getDB()->getTechnology()->getBasicLayers() ) {
unsigned int gdsNumber = layer->getGds2Layer();
if (gdsNumber < 64) _gdsLayerTable[gdsNumber] = layer;
uint16_t gdsNumber = layer->getGds2Layer();
if (gdsNumber < 1024) _gdsLayerTable[gdsNumber] = layer;
}
}
@ -938,7 +938,7 @@ namespace {
if (_record.isELFLAGS()) { _stream >> _record; }
if (_record.isPLEX ()) { _stream >> _record; }
if (_record.isLAYER ()) {
layer = gdsToLayer( _record.getInt16s()[0] );
layer = gdsToLayer( (uint16_t)_record.getInt16s()[0] );
if (not layer) {
cerr << Error( "GdsStream::readText(): No BasicLayer id:%d in GDS conversion table (skipped)."
, _record.getInt16s()[0]
@ -1051,7 +1051,8 @@ namespace {
if (_record.isPLEX ()) { _stream >> _record; }
if (_record.isLAYER()) {
layer = gdsToLayer( _record.getInt16s()[0] );
layer = gdsToLayer( (uint16_t)_record.getInt16s()[0] );
cdebug_log(101,0) << "Layer id:" << ((uint32_t)_record.getInt16s()[0]) << " " << layer << endl;
if (not layer) {
cerr << Error( "GdsStream::readBoundary(): No BasicLayer id:%d in GDS conversion table (skipped)."
, _record.getInt16s()[0]
@ -1099,7 +1100,7 @@ namespace {
if (_record.isPLEX ()) { _stream >> _record; }
if (_record.isLAYER()) {
layer = gdsToLayer( _record.getInt16s()[0] );
layer = gdsToLayer( (uint16_t)_record.getInt16s()[0] );
if (not layer) {
cerr << Error( "GdsStream::readPath(): No BasicLayer id \"%d\" in GDS conversion table (skipped)."
, _record.getInt16s()[0]
@ -1285,7 +1286,16 @@ namespace {
if (_record.isELFLAGS()) { _stream >> _record; }
if (_record.isPLEX ()) { _stream >> _record; }
if (_record.isLAYER ()) { _stream >> _record; }
if (_record.isLAYER ()) {
layer = gdsToLayer( (uint16_t)_record.getInt16s()[0] );
if (not layer) {
cerr << Error( "GdsStream::readNode(): No BasicLayer id \"%d\" in GDS conversion table (skipped)."
, _record.getInt16s()[0]
) << endl;
}
_stream >> _record;
cdebug_log(101,0) << layer << endl;
}
else { _validSyntax = false; return _validSyntax; }
if (_record.isNODETYPE()) {
@ -1315,7 +1325,16 @@ namespace {
if (_record.isELFLAGS()) { _stream >> _record; }
if (_record.isPLEX ()) { _stream >> _record; }
if (_record.isLAYER ()) { _stream >> _record; }
if (_record.isLAYER ()) {
layer = gdsToLayer( (uint16_t)_record.getInt16s()[0] );
if (not layer) {
cerr << Error( "GdsStream::readNode(): No BasicLayer id \"%d\" in GDS conversion table (skipped)."
, _record.getInt16s()[0]
) << endl;
}
_stream >> _record;
cdebug_log(101,0) << layer << endl;
}
else { _validSyntax = false; return _validSyntax; }
if (_record.isBOXTYPE()) {
@ -1424,8 +1443,8 @@ namespace {
} else {
_component = Rectilinear::create( net, layer, points );
}
// cdebug(101,0) << "| " << net->getCell() << endl;
// cdebug(101,0) << "| " << _component << endl;
// cdebug_log(101,0) << "| " << net->getCell() << endl;
cdebug_log(101,0) << "| " << _component << endl;
if (not net->isAutomatic()) NetExternalComponents::setExternal( _component );
}

View File

@ -120,7 +120,7 @@ class Chip ( Block ):
if self.conf.routingGauge.hasPowerSupply():
power = plugins.alpha.chip.powerplane.Builder( self.conf )
power.connectPower()
power.connectHTrees( self.hTrees )
#power.connectHTrees( self.hTrees )
power.doLayout()
Breakpoint.stop( 101, 'After Query power.' )
else:

View File

@ -27,6 +27,7 @@ from helpers.overlay import UpdateSession
import plugins
import plugins.chip
from plugins.alpha.block.bigvia import BigVia
from plugins.alpha.block.configuration import GaugeConf
__all__ = [ 'Builder' ]
@ -489,11 +490,6 @@ class Builder ( object ):
raise ErrorMessage( 1, message )
with UpdateSession():
coronaAb = self.conf.cellPnR.getAbutmentBox()
bufferRp = self.conf.rpAccessByOccurrence( Occurrence(htPlugs[0], Path()), coronaNet, 0 )
pinRp = self.conf.rpAccessByOccurrence( Occurrence(coronaPin , Path()), coronaNet, 0 )
trace( 550, '\tpinRp={}\n'.format(pinRp) )
self.conf.expandMinArea( bufferRp )
self.conf.expandMinArea( pinRp )
if coronaPin.getAccessDirection() == Pin.Direction.NORTH:
isVertical = True
axis = coronaAb.getYMax()
@ -508,6 +504,10 @@ class Builder ( object ):
elif coronaPin.getAccessDirection() == Pin.Direction.WEST:
isVertical = False
axis = coronaAb.getXMin()
flags = 0 if isVertical else GaugeConf.HAccess
bufferRp = self.conf.rpAccessByOccurrence( Occurrence(htPlugs[0], Path()), coronaNet, flags )
pinRp = self.conf.rpAccessByOccurrence( Occurrence(coronaPin , Path()), coronaNet, flags )
trace( 550, '\tpinRp={}\n'.format(pinRp) )
if isVertical:
pitch = self.conf.hRoutingGauge.getPitch()
yaxis = axis + 2 * pitch * trackNb
@ -537,6 +537,8 @@ class Builder ( object ):
self.conf.createVertical ( contact1, contact2, xaxis , 0 )
self.conf.createHorizontal( contact2, pinRp , yaxisPin, 0 )
trace( 550, '\txaxis(track)={}\n'.format(DbU.getValueString(xaxis)) )
self.conf.expandMinArea( bufferRp )
self.conf.expandMinArea( pinRp )
return
def connectHTrees ( self, hTrees ):

View File

@ -120,32 +120,47 @@ namespace {
void GapSet::merge ( size_t i )
{
// cerr << "GapSet::merge() " << _track->getSegment( i ) << endl;
TrackElement* element = _track->getSegment( i );
uint64_t id = element->getNet()->getId();
if (_spans.empty()) {
//if (id == 317015)
// cerr << "GapSet::merge() new range " << i
// << " " << _track->getSegment(i) << endl;
_spans.push_back( make_pair(i,i) );
return;
}
size_t ispan = 0;
TrackElement* element = _track->getSegment( i );
DbU::Unit segSourceU = element->getSourceU()+_halfSpacing;
DbU::Unit segTargetU = element->getTargetU()-_halfSpacing;
//if (id == 317015)
// cerr << "GapSet::merge() " << element << endl;
for ( ; ispan<_spans.size() ; ++ispan ) {
if (targetU(ispan) >= segSourceU) {
if (targetU(ispan) >= segTargetU)
if (targetU(ispan) >= segTargetU) {
//if (id == 317015)
// cerr << "GapSet::merge() already inside range" << endl;
return;
}
_spans[ispan].second = i;
//if (id == 317015)
// cerr << "GapSet::merge() becomes range end" << endl;
break;
}
}
if (ispan == _spans.size()) {
_spans.push_back( make_pair(i,i) );
//if (id == 317015)
// cerr << "GapSet::merge() new range" << endl;
return;
}
while ( ispan+1 < _spans.size() ) {
if (targetU(ispan) >= sourceU(ispan+1)) {
_spans[ispan].second = std::max( targetU(ispan), targetU(ispan+1) );
_spans.erase( _spans.begin()+ispan+1 );
//if (id == 317015)
// cerr << "GapSet::merge() fuse with next range" << endl;
}
}
}
@ -988,16 +1003,23 @@ namespace Katana {
uint32_t Track::repair () const
{
// cerr << "Track::repair() " << this << endl;
if (_segments.empty()) return 0;
DbU::Unit minSpacing = getLayer()->getMinimalSpacing();
bool netChange = false;
uint32_t gaps = 0;
GapSet gapsetPrev ( this );
GapSet gapsetCurr ( this );
for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) {
// if (getIndex() == 1750)
// cerr << "[" << i << "] " << _segments[i] << endl;
netChange = false;
gapsetCurr.merge( i );
if ( (_segments[i]->getNet() != _segments[i+1]->getNet())
or _segments[i]->getLayer()->isBlockage() ) {
netChange = true;
if (gapsetPrev.size() and gapsetCurr.size()) {
DbU::Unit spacing = gapsetCurr.spansSourceU() - gapsetPrev.spansTargetU();
if (spacing < minSpacing) {
@ -1021,7 +1043,12 @@ namespace Katana {
}
}
}
}
if ((i+2 == _segments.size()) and (_segments[i]->getNet() == _segments[i+1]->getNet()))
gapsetCurr.merge( i+1 );
if (netChange or (i+2 == _segments.size())) {
if (gapsetCurr.size() > 1) {
// cerr << "potential gap around " << _segments[i] << endl;
for ( size_t j=0 ; j+1 < gapsetCurr.size() ; ++j ) {
@ -1036,9 +1063,12 @@ namespace Katana {
// << " " << DbU::getValueString(gapsetCurr.targetU(j)) << "], "
// << j+1 << "=[" << DbU::getValueString(gapsetCurr.sourceU(j+1))
// << " " << DbU::getValueString(gapsetCurr.targetU(j+1)) << "]" << endl;
if (gapsetCurr.span(j+1).first >= _segments.size()) {
cerr << Error("gapsetCurr.span(j+1).first >= _segments.size()") << endl;
} else {
AutoSegment* first = _segments[gapsetCurr.span(j+1).first]->base();
cerr << "spacing:" << DbU::getValueString(spacing) << " " << first << endl;
// cerr << "spacing:" << DbU::getValueString(spacing) << " " << first << endl;
if (first == NULL) {
cerr << Error("null first, NOT correcting gap") << endl;
} else {
@ -1052,11 +1082,13 @@ namespace Katana {
++gaps;
cerr << Warning( " Track::repair(): Closing same net gap in %s near:\n %s"
, getString(this).c_str()
, getString(_segments[i-1]).c_str() ) << endl;
//cerr << first << endl;
, getString(_segments[(i) ? i-1 : 0]).c_str() ) << endl;
// cerr << first << endl;
}
}
}
}
gapsetPrev.swap( gapsetCurr );
gapsetCurr.clear();
}