Merge branch 'master' into robtaylor/room-link
This commit is contained in:
commit
c9cbf87c10
|
@ -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
|
||||
=======
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue