Merge branch 'master' into robtaylor/room-link

This commit is contained in:
Rob Taylor 2023-07-17 18:57:44 +01:00 committed by GitHub
commit c9cbf87c10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 111 additions and 27 deletions

View File

@ -11,6 +11,7 @@ This project is hosted at: https://github.com/lip6/coriolis
Development discussion can be found at https://matrix.to/#/#coriolis:matrix.org
Purpose
=======

View File

@ -1782,6 +1782,18 @@ namespace {
NetExternalComponents::setExternal( p );
toDestroy.push_back( component );
cdebug_log(101,0) << "> external duplicate " << p << endl;
} else {
Rectilinear* rectilinear = dynamic_cast<Rectilinear*>( component );
if (rectilinear) {
rectilinear = Rectilinear::create( net
, rectilinear->getLayer()
, rectilinear->getPoints() );
NetExternalComponents::setExternal( rectilinear );
} else {
cerr << Error( "GdsStream::makeExternals(): Unmanaged component %s for net \"%s\"."
, getString(component).c_str()
, getString(net->getName()).c_str() ) << endl;
}
}
}
}

View File

@ -615,8 +615,6 @@ namespace {
Net* net = Net::create( parser->getCell(), pin->name() );
net->setExternal( true );
if (pin->name()[ strlen(pin->name())-1 ] == '!') net->setGlobal( true );
if (pin->hasDirection()) {
string lefDir = pin->direction();
boost::to_upper( lefDir );
@ -637,6 +635,8 @@ namespace {
if (lefUse == "POWER" ) net->setType( Net::Type::POWER );
if (lefUse == "GROUND") net->setType( Net::Type::GROUND );
}
if (net->isSupply()) net->setGlobal( true );
if (pin->name()[ strlen(pin->name())-1 ] == '!') net->setGlobal( true );
for ( int iport=0 ; iport < pin->numPorts() ; ++iport ) {
Layer* layer = NULL;
@ -727,27 +727,30 @@ namespace {
const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 );
Box ab = _cell->getAbutmentBox();
cerr << " @ _pinStdPostProcess" << endl;
//cerr << " @ _pinStdPostProcess" << endl;
for ( auto element : _pinComponents ) {
string pinName = element.first;
vector<Component*>& components = element.second;
vector<Segment*> ongrids;
bool isSupply = false;
for ( Component* component : components ) {
if (component->getNet()->isSupply()) {
isSupply = true;
break;
}
Segment* segment = dynamic_cast<Segment*>( component );
if (segment) {
if (component->getNet()->isSupply()) continue;
bool isWide = (segment->getWidth() >= getMinTerminalWidth());
cerr << " > " << segment << endl;
if (not isVH())
cerr << "NOT isVH()" << endl;
else
cerr << "isVH()" << endl;
// cerr << " > " << segment << endl;
// if (not isVH()) cerr << "X NOT isVH()" << endl;
// else cerr << "X isVH()" << endl;
if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) {
cerr << "isVH()" << endl;
// cerr << "isVH()" << endl;
Vertical* v = dynamic_cast<Vertical*>( segment );
if (v) {
DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin()
@ -775,7 +778,7 @@ namespace {
, v->getDyTarget()
)
);
//cerr << " | " << ongrids[ongrids.size()-1] << endl;
cerr << " | " << ongrids[ongrids.size()-1] << endl;
} else {
// Unpitched and not wide enough to be under a metal2 track, ignore.
}
@ -788,11 +791,11 @@ namespace {
if (isWide) ongrids.push_back( segment );
}
Rectilinear* rectilinear = dynamic_cast<Rectilinear*>( component );
if (not (rectilinear->getLayer()->getMask() == metal1->getMask()))
continue;
if (rectilinear) {
cerr << " > " << rectilinear << endl;
if (rectilinear->getLayer()->getMask() != metal1->getMask())
continue;
vector<Box> boxes;
rectilinear->getAsRectangles( boxes );
@ -841,8 +844,9 @@ namespace {
}
if (ongrids.empty()) {
cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" has no terminal ongrid."
, pinName.c_str() ) << endl;
if (not isSupply)
cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" has no terminal ongrid."
, pinName.c_str() ) << endl;
for ( Component* component : components ) {
NetExternalComponents::setExternal( component );
}
@ -1008,7 +1012,7 @@ namespace {
if (parser->getCoreSiteY() != parser->getCellGauge()->getSliceHeight())
cerr << Warning( "LefParser::parse(): CRL slice height discrepency %s while LEF is %s."
, DbU::getValueString(parser->getCellGauge()->getSliceHeight()).c_str()
, DbU::getValueString(parser->getCoreSiteX()).c_str() ) << endl;
, DbU::getValueString(parser->getCoreSiteY()).c_str() ) << endl;
if (parser->getCoreSiteX() != parser->getCellGauge()->getSliceStep())
cerr << Warning( "LefParser::parse(): CRL slice step discrepency %s while LEF is %s."

View File

@ -744,7 +744,10 @@ class IoPadConf ( object ):
else:
if self._datas[5] is not None: self.flags |= IoPadConf.BIDIR
elif self._datas[6] is not None: self.flags |= IoPadConf.TRISTATE
trace( 550, '\tIoPadConf._datas: {}\n'.format(self._datas) )
sPos = ''
if self._datas[1]:
sPos = DbU.getValueString(self._datas[1])
trace( 550, '\tIoPadConf._datas: @{} {}\n'.format(sPos,self._datas) )
@property
def side ( self ): return self._datas[0]

View File

@ -106,7 +106,11 @@ class HTree ( object ):
hLeafDepth = gaugeConf.horizontalDepth - 2
gaugeConf.setStackPosition( contact, x, y )
gaugeConf.createVertical ( contact, forkContact, x, 0 )
gaugeConf.addTrackAvoid( Box( x, forkContact.getY(), x, y ) )
trackAvoidBox = Box( x, forkContact.getY(), x, y )
if forkContact.getY() > contact.getY():
trackAvoidBox.inflate( 0, 0, 0, self.spares.conf.sliceHeight )
gaugeConf.addTrackAvoid( trackAvoidBox )
self.spares.trackAvoid( trackAvoidBox )
if len(leaf.buffers) > 1:
tl1Contact = gaugeConf.rpAccessByPlugName( leaf.buffers[1], bufferConf.input, ckNet, GaugeConf.DeepDepth|GaugeConf.HAccess )
tl2Contact = gaugeConf.rpAccessByPlugName( leaf.buffers[2], bufferConf.input, ckNet )

View File

@ -1103,8 +1103,8 @@ class Spares ( object ):
trace( 540, ',+', '\tSpares.addStrayBuffer()\n' )
sliceHeight = self.conf.sliceHeight
x = self.quadTree.toXPitch( position.getX() )
y = self.quadTree.toYSlice( position.getY() )
x = self.toXPitch( position.getX() )
y = self.toYSlice( position.getY() )
slice = y // sliceHeight
orientation = Transformation.Orientation.ID
y = slice * sliceHeight
@ -1134,6 +1134,37 @@ class Spares ( object ):
raise ErrorMessage( 2, 'Spares.getFreeBufferUnder(): No more free buffers under {}.'.format(area) )
return leaf.selectFree()
def trackAvoid ( self, box ):
"""
Protect a vertical track by putting a vertical column of narrow filler
under it (usually tie). Used by the H-Tree (clock tree) in low-metal
nodes.
"""
trace( 540, ',+', '\tSpares.trackAvoid() {}\n'.format( box ))
yoffset = 0
if self.conf.isCoreBlock:
yoffset = self.conf.icore.getTransformation().getTy()
sliceHeight = self.conf.sliceHeight
x = self.toXPitch( box.getXMin() ) - self.conf.sliceStep
ymin = self.toYSlice( box.getYMin() )
ymax = self.toYSlice( box.getYMax() )
sliceMin = (ymin - yoffset) // sliceHeight
sliceMax = (ymax - yoffset) // sliceHeight
orientation = Transformation.Orientation.ID
ymin = sliceMin * sliceHeight
for row in range( sliceMin+1, sliceMax ):
orientation = Transformation.Orientation.ID
y = row * sliceHeight + yoffset
if row%2:
orientation = Transformation.Orientation.MY
y += sliceHeight
transf = Transformation( x, y, orientation )
instance = self.conf.feedsConf.createFeed( self.conf.corona )
instance.setTransformation( transf )
instance.setPlacementStatus( Instance.PlacementStatus.FIXED )
trace( 540, '\ttrackAvoid, feed: {} @{}\n'.format(instance,transf) )
trace( 540, '-' )
def raddTransNet ( self, topNet, path ):
"""
Add a net through a whole hierarchy of Instance/Cells. The master cells

View File

@ -169,7 +169,7 @@ class Side ( object ):
self.type = sideType
self.corona = corona
self.pins = []
self.u = self.conf.ioPadHeight
self.u = 0
self.spacerCount = 0
self.gap = 0
self.coreWires = []
@ -370,6 +370,10 @@ class Side ( object ):
return
def _placePads ( self ):
if self.type in (North,South):
self.u = self.corona.padCornerWidth
else:
self.u = self.corona.padCornerHeight
padLength = 0
for pad in self.pads: padLength += pad[1].getMasterCell().getAbutmentBox().getWidth()
padSpacing = (self.sideLength - 2*self.conf.ioPadHeight - padLength) // (len(self.pads) + 1)
@ -551,6 +555,8 @@ class Corona ( object ):
self.padCorner = []
self.padRails = [] # [ , [net, layer, axis, width] ]
self.powerCount = 0
self.padCornerWidth = self.conf.ioPadHeight
self.padCornerHeight = self.conf.ioPadHeight
self.conf.cfg.chip.padCoreSide = None
if self.conf.cfg.chip.padCoreSide.lower() == 'south':
self.padOrient = Transformation.Orientation.MY
@ -567,7 +573,9 @@ class Corona ( object ):
raise ErrorMessage( 1, 'Corona.__init__(): Missing spacer cell "{}"'.format(spacerName) )
self.padSpacers = sorted( self.padSpacers, key=_cmpPad, reverse=True )
if self.conf.cfg.chip.padCorner is not None:
self.padCorner = self.padLib.getCell( self.conf.cfg.chip.padCorner )
self.padCorner = self.padLib.getCell( self.conf.cfg.chip.padCorner )
self.padCornerWidth = self.padCorner.getAbutmentBox().getWidth()
self.padCornerHeight = self.padCorner.getAbutmentBox().getHeight()
if self.conf.cfg.chip.minPadSpacing is None:
self.conf.cfg.chip.minPadSpacing = 0

View File

@ -24,6 +24,7 @@
#include "hurricane/Plug.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Path.h"
#include "hurricane/Library.h"
@ -50,6 +51,7 @@ namespace Etesian {
using Hurricane::Plug;
using Hurricane::RoutingPad;
using Hurricane::Vertical;
using Hurricane::Horizontal;
using Hurricane::NetExternalComponents;
using Hurricane::DebugSession;
using Hurricane::UpdateSession;
@ -57,6 +59,8 @@ namespace Etesian {
using CRL::CatalogExtension;
using CRL::getTransformation;
using CRL::RoutingLayerGauge;
using Constant::LayerGaugeType;
using Constant::Direction;
using Etesian::EtesianEngine;
@ -146,7 +150,7 @@ namespace Etesian {
return;
}
list<Tile>::iterator imerge = _tiles.end();
//list<Tile>::iterator imerge = _tiles.end();
for ( auto itile = _tiles.begin() ; itile != _tiles.end() ; ++itile ) {
if ((*itile).getXMin() > flatAb.getXMin()) {
_tiles.insert( itile, Tile(flatAb.getXMin(), flatAb.getWidth(), occurrence) );
@ -630,12 +634,15 @@ namespace Etesian {
if (not component->getLayer()->isBlockage()) continue;
cdebug_log(121,0) << "Looking at " << component << endl;
Vertical* v = dynamic_cast<Vertical*>( component );
if (not v) continue;
if ( not dynamic_cast<Vertical* >(component)
and not dynamic_cast<Horizontal*>(component)) continue;
RoutingLayerGauge* rlg = rg->getLayerGauge( v->getLayer()->getRoutingLayer() );
RoutingLayerGauge* rlg = rg->getLayerGauge( component->getLayer()->getRoutingLayer() );
if (not rlg) continue;
if (rlg->getType() != LayerGaugeType::Default) continue;
if (rlg->getDirection() != Direction::Vertical) continue;
Box bb = v->getBoundingBox();
Box bb = component->getBoundingBox();
bb.inflate( -rlg->getWireWidth()/2, 0 );
Transformation transf = tile.getInstance()->getTransformation();
tile.getOccurrence().getPath().getTransformation().applyOn( transf );

View File

@ -479,6 +479,19 @@ namespace Hurricane {
}
Box Rectilinear::getNearestHSide ( DbU::Unit y ) const
{
Box side;
for ( size_t i=1 ; i<_points.size() ; ++i ) {
if (_points[i-1].getY() != _points[i].getY()) continue;
if ( not side.isEmpty()
and (std::abs(side.getYCenter() - y) >= std::abs(_points[i].getY() - y))) continue;
side = Box( _points[i-1], _points[i] );
}
return side;
}
void Rectilinear::_toJson ( JsonWriter* writer ) const
{
Inherit::_toJson( writer );

View File

@ -60,6 +60,7 @@ namespace Hurricane {
inline Points getContour () const;
bool getAsRectangles ( std::vector<Box>& ) const;
inline const vector<Point>& getPoints () const;
Box getNearestHSide ( DbU::Unit y ) const;
// Mutators.
void setLayer ( const Layer* );
virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy );