Merge pull request #10 from lip6/small-fixes
This commit is contained in:
commit
ae084b7431
|
@ -1672,19 +1672,19 @@ namespace {
|
||||||
, vWidthCap );
|
, vWidthCap );
|
||||||
cdebug_log(101,0) << "+ " << target << endl;
|
cdebug_log(101,0) << "+ " << target << endl;
|
||||||
if (points[i-1].getY() == points[i].getY()) {
|
if (points[i-1].getY() == points[i].getY()) {
|
||||||
segment = Horizontal::create( source
|
segment = Horizontal::create( source->getNet()
|
||||||
, target
|
|
||||||
, layer
|
, layer
|
||||||
, points[i].getY()
|
, points[i].getY()
|
||||||
, width
|
, width
|
||||||
, 0, 0 );
|
, source->getX()
|
||||||
|
, target->getX() );
|
||||||
} else {
|
} else {
|
||||||
segment = Vertical::create( source
|
segment = Vertical::create( source->getNet()
|
||||||
, target
|
|
||||||
, layer
|
, layer
|
||||||
, points[i].getX()
|
, points[i].getX()
|
||||||
, width
|
, width
|
||||||
, 0, 0 );
|
, source->getY()
|
||||||
|
, target->getY() );
|
||||||
}
|
}
|
||||||
cdebug_log(101,0) << "| " << segment << endl;
|
cdebug_log(101,0) << "| " << segment << endl;
|
||||||
if (not net->isAutomatic()) NetExternalComponents::setExternal( segment );
|
if (not net->isAutomatic()) NetExternalComponents::setExternal( segment );
|
||||||
|
|
|
@ -85,6 +85,8 @@ namespace {
|
||||||
inline bool isVH () const;
|
inline bool isVH () const;
|
||||||
bool isUnmatchedLayer ( string );
|
bool isUnmatchedLayer ( string );
|
||||||
Library* createLibrary ();
|
Library* createLibrary ();
|
||||||
|
Cell* earlyGetCell ( string name="" );
|
||||||
|
Net* earlyGetNet ( string name );
|
||||||
inline string getLibraryName () const;
|
inline string getLibraryName () const;
|
||||||
inline Library* getLibrary ( bool create=false );
|
inline Library* getLibrary ( bool create=false );
|
||||||
inline string getForeignPath () const;
|
inline string getForeignPath () const;
|
||||||
|
@ -349,6 +351,27 @@ namespace {
|
||||||
return _library;
|
return _library;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Cell* LefParser::earlyGetCell ( string name )
|
||||||
|
{
|
||||||
|
if (not _cell) {
|
||||||
|
if (name.empty())
|
||||||
|
name = "EarlyLEFCell";
|
||||||
|
_cell = Cell::create( getLibrary(true), name );
|
||||||
|
}
|
||||||
|
return _cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Net* LefParser::earlyGetNet ( string name )
|
||||||
|
{
|
||||||
|
if (not _cell) earlyGetCell();
|
||||||
|
Net* net = _cell->getNet( name );
|
||||||
|
if (not net)
|
||||||
|
net = Net::create( _cell, name );
|
||||||
|
return net;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int LefParser::_unitsCbk ( lefrCallbackType_e c, lefiUnits* units, lefiUserData ud )
|
int LefParser::_unitsCbk ( lefrCallbackType_e c, lefiUnits* units, lefiUserData ud )
|
||||||
{
|
{
|
||||||
|
@ -505,10 +528,10 @@ namespace {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LefParser::_macroForeignCbk ( lefrCallbackType_e c, const lefiMacroForeign* foreign, lefiUserData ud )
|
int LefParser::_macroForeignCbk ( lefrCallbackType_e c, const lefiMacroForeign* foreign, lefiUserData ud )
|
||||||
{
|
{
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
AllianceFramework* af = AllianceFramework::get();
|
|
||||||
|
|
||||||
if (_gdsForeignDirectory.empty()) {
|
if (_gdsForeignDirectory.empty()) {
|
||||||
cerr << Warning( "LefParser::_macroForeignCbk(): GDS directory *not* set, ignoring FOREIGN statement." ) << endl;
|
cerr << Warning( "LefParser::_macroForeignCbk(): GDS directory *not* set, ignoring FOREIGN statement." ) << endl;
|
||||||
|
@ -520,9 +543,25 @@ namespace {
|
||||||
parser->setForeignPosition( Point( parser->fromUnitsMicrons( foreign->px() )
|
parser->setForeignPosition( Point( parser->fromUnitsMicrons( foreign->px() )
|
||||||
, parser->fromUnitsMicrons( foreign->px() )));
|
, parser->fromUnitsMicrons( foreign->px() )));
|
||||||
|
|
||||||
|
Cell* cell = parser->earlyGetCell( foreign->cellName() );
|
||||||
|
|
||||||
|
Gds::load( parser->getLibrary(), parser->getForeignPath()
|
||||||
|
, Gds::NoGdsPrefix|Gds::NoBlockages|Gds::Layer_0_IsBoundary);
|
||||||
|
for ( Net* net : cell->getNets() ) {
|
||||||
|
if (net->isPower ()) parser->setGdsPower ( net );
|
||||||
|
if (net->isGround()) parser->setGdsGround( net );
|
||||||
|
if (parser->getForeignPosition() != Point(0,0)) {
|
||||||
|
for ( Component* component : net->getComponents() ) {
|
||||||
|
component->translate( parser->getForeignPosition().getX()
|
||||||
|
, parser->getForeignPosition().getY() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LefParser::_obstructionCbk ( lefrCallbackType_e c, lefiObstruction* obstruction, lefiUserData ud )
|
int LefParser::_obstructionCbk ( lefrCallbackType_e c, lefiObstruction* obstruction, lefiUserData ud )
|
||||||
{
|
{
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
|
@ -600,33 +639,16 @@ namespace {
|
||||||
AllianceFramework* af = AllianceFramework::get();
|
AllianceFramework* af = AllianceFramework::get();
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
|
|
||||||
parser->setCellGauge( NULL );
|
parser->setCellGauge( nullptr );
|
||||||
|
|
||||||
string cellName = macro->name();
|
string cellName = macro->name();
|
||||||
DbU::Unit width = 0;
|
DbU::Unit width = 0;
|
||||||
DbU::Unit height = 0;
|
DbU::Unit height = 0;
|
||||||
Cell* cell = parser->getCell();
|
Cell* cell = parser->earlyGetCell();
|
||||||
|
|
||||||
if (cell) {
|
if (cell->getName() != Name(cellName)) {
|
||||||
|
cerr << cell << " -> " << cellName << endl;
|
||||||
cell->setName( cellName );
|
cell->setName( cellName );
|
||||||
} else {
|
|
||||||
cell = Cell::create( parser->getLibrary(true), cellName );
|
|
||||||
parser->setCell( cell );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not parser->getForeignPath().empty()) {
|
|
||||||
Gds::load( parser->getLibrary(), parser->getForeignPath()
|
|
||||||
, Gds::NoGdsPrefix|Gds::NoBlockages|Gds::Layer_0_IsBoundary);
|
|
||||||
for ( Net* net : cell->getNets() ) {
|
|
||||||
if (net->isPower ()) parser->setGdsPower ( net );
|
|
||||||
if (net->isGround()) parser->setGdsGround( net );
|
|
||||||
if (parser->getForeignPosition() != Point(0,0)) {
|
|
||||||
for ( Component* component : net->getComponents() ) {
|
|
||||||
component->translate( parser->getForeignPosition().getX()
|
|
||||||
, parser->getForeignPosition().getY() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (macro->hasSize()) {
|
if (macro->hasSize()) {
|
||||||
|
@ -673,7 +695,9 @@ namespace {
|
||||||
| Catalog::State::InMemory
|
| Catalog::State::InMemory
|
||||||
| Catalog::State::TerminalNetlist, true );
|
| Catalog::State::TerminalNetlist, true );
|
||||||
cell->setTerminalNetlist( true );
|
cell->setTerminalNetlist( true );
|
||||||
parser->setCell( NULL );
|
parser->setCell ( nullptr );
|
||||||
|
parser->setGdsPower ( nullptr );
|
||||||
|
parser->setGdsGround( nullptr );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -689,7 +713,7 @@ namespace {
|
||||||
|
|
||||||
//cerr << " @ _pinCbk: " << pin->name() << endl;
|
//cerr << " @ _pinCbk: " << pin->name() << endl;
|
||||||
|
|
||||||
if (not parser->getCell()) parser->setCell( Cell::create( parser->getLibrary(true), "LefImportTmpCell" ) );
|
parser->earlyGetCell();
|
||||||
|
|
||||||
Net* net = nullptr;
|
Net* net = nullptr;
|
||||||
Net::Type netType = Net::Type::UNDEFINED;
|
Net::Type netType = Net::Type::UNDEFINED;
|
||||||
|
@ -718,7 +742,7 @@ namespace {
|
||||||
net->setName( pin->name() );
|
net->setName( pin->name() );
|
||||||
parser->setGdsGround( nullptr );
|
parser->setGdsGround( nullptr );
|
||||||
} else {
|
} else {
|
||||||
net = Net::create( parser->getCell(), pin->name() );
|
net = parser->earlyGetNet( pin->name() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
net->setExternal( true );
|
net->setExternal( true );
|
||||||
|
|
|
@ -661,7 +661,8 @@ class GaugeConf ( object ):
|
||||||
class IoPadConf ( object ):
|
class IoPadConf ( object ):
|
||||||
"""
|
"""
|
||||||
Store all informations related to an I/O pad. It's side, position
|
Store all informations related to an I/O pad. It's side, position
|
||||||
and connected nets.
|
and connected nets. The kind of pad is guessed from the number of
|
||||||
|
nets.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
@ -669,6 +670,7 @@ class IoPadConf ( object ):
|
||||||
( IoPin.SOUTH, None, 'a_0' , 'a(0)' , 'a(0)' )
|
( IoPin.SOUTH, None, 'a_0' , 'a(0)' , 'a(0)' )
|
||||||
( IoPin.NORTH, None, 'p_r0' , 'r0' , 'r0_from_pads', 'shift_r' , 'r0_to_pads' )
|
( IoPin.NORTH, None, 'p_r0' , 'r0' , 'r0_from_pads', 'shift_r' , 'r0_to_pads' )
|
||||||
( IoPin.NORTH, None, 'p_y0' , 'y(0)' , 'y_oe' , 'y_to_pads(0)' )
|
( IoPin.NORTH, None, 'p_y0' , 'y(0)' , 'y_oe' , 'y_to_pads(0)' )
|
||||||
|
( IoPin.NORTH, None, 'nc_0' )
|
||||||
|
|
||||||
self._datas is a table of 8 elements, the seven first coming from
|
self._datas is a table of 8 elements, the seven first coming from
|
||||||
the configuration itself. Direction are taken from the core point
|
the configuration itself. Direction are taken from the core point
|
||||||
|
@ -710,17 +712,20 @@ class IoPadConf ( object ):
|
||||||
CLOCK = 0x0040
|
CLOCK = 0x0040
|
||||||
TRISTATE = 0x0080
|
TRISTATE = 0x0080
|
||||||
BIDIR = 0x0100
|
BIDIR = 0x0100
|
||||||
|
NON_CONNECT = 0x0200
|
||||||
|
|
||||||
def __init__ ( self, datas ):
|
def __init__ ( self, datas ):
|
||||||
if not isinstance(datas,tuple):
|
if isinstance(datas,list ): self._datas = datas
|
||||||
raise ErrorMessage( 1, [ 'IoPadConf.__init__(): The "datas" parameter is not a tuple.'
|
elif isinstance(datas,tuple): self._datas = list( datas )
|
||||||
|
else:
|
||||||
|
raise ErrorMessage( 1, [ 'IoPadConf.__init__(): The "datas" parameter is neither a list nor a tuple.'
|
||||||
, str(datas) ] )
|
, str(datas) ] )
|
||||||
if len(datas) < 5 and len(datas) > 8:
|
if len(datas) != 3 and len(datas) < 5 and len(datas) > 8:
|
||||||
raise ErrorMessage( 1, [ 'IoPadConf.__init__(): The "datas" list must have between 5 to 7 elements.'
|
raise ErrorMessage( 1, [ 'IoPadConf.__init__(): The "datas" list must have between 5 to 7 elements.'
|
||||||
, str(datas) ] )
|
, str(datas) ] )
|
||||||
self.flags = 0
|
self.flags = 0
|
||||||
self.index = None
|
self.index = None
|
||||||
self._datas = list( datas )
|
if len(self._datas) == 3: self._datas += [ None, None, None, None ]
|
||||||
if len(self._datas) == 4: self._datas += [ None, None, None ]
|
if len(self._datas) == 4: self._datas += [ None, None, None ]
|
||||||
if len(self._datas) == 5: self._datas += [ None, None ]
|
if len(self._datas) == 5: self._datas += [ None, None ]
|
||||||
elif len(self._datas) == 6: self._datas.insert( 5, None )
|
elif len(self._datas) == 6: self._datas.insert( 5, None )
|
||||||
|
@ -742,7 +747,8 @@ class IoPadConf ( object ):
|
||||||
if m.group('type') == 'ground': self.flags |= IoPadConf.CORE_GROUND
|
if m.group('type') == 'ground': self.flags |= IoPadConf.CORE_GROUND
|
||||||
if m.group('type') == 'clock' : self.flags |= IoPadConf.CLOCK
|
if m.group('type') == 'clock' : self.flags |= IoPadConf.CLOCK
|
||||||
else:
|
else:
|
||||||
if self._datas[5] is not None: self.flags |= IoPadConf.BIDIR
|
if self._datas[3] is None: self.flags |= IoPadConf.NON_CONNECT
|
||||||
|
elif self._datas[5] is not None: self.flags |= IoPadConf.BIDIR
|
||||||
elif self._datas[6] is not None: self.flags |= IoPadConf.TRISTATE
|
elif self._datas[6] is not None: self.flags |= IoPadConf.TRISTATE
|
||||||
sPos = ''
|
sPos = ''
|
||||||
if self._datas[1]:
|
if self._datas[1]:
|
||||||
|
@ -799,6 +805,7 @@ class IoPadConf ( object ):
|
||||||
def isClock ( self ): return self.flags & IoPadConf.CLOCK
|
def isClock ( self ): return self.flags & IoPadConf.CLOCK
|
||||||
def isTristate ( self ): return self.flags & IoPadConf.TRISTATE
|
def isTristate ( self ): return self.flags & IoPadConf.TRISTATE
|
||||||
def isBidir ( self ): return self.flags & IoPadConf.BIDIR
|
def isBidir ( self ): return self.flags & IoPadConf.BIDIR
|
||||||
|
def isNonConnect ( self ): return self.flags & IoPadConf.NON_CONNECT
|
||||||
|
|
||||||
def isAnalog ( self ):
|
def isAnalog ( self ):
|
||||||
if self._datas[0] is None: return False
|
if self._datas[0] is None: return False
|
||||||
|
@ -1411,6 +1418,7 @@ class BlockConf ( GaugeConf ):
|
||||||
self.katana = None
|
self.katana = None
|
||||||
|
|
||||||
def _postInit ( self ):
|
def _postInit ( self ):
|
||||||
|
trace( 550, ',+', '\tblock.configuration._postInit()\n' )
|
||||||
self.cfg.apply()
|
self.cfg.apply()
|
||||||
self.bufferConf = BufferConf( self.framework )
|
self.bufferConf = BufferConf( self.framework )
|
||||||
self.constantsConf = ConstantsConf( self.framework, self.cfg )
|
self.constantsConf = ConstantsConf( self.framework, self.cfg )
|
||||||
|
@ -1420,6 +1428,7 @@ class BlockConf ( GaugeConf ):
|
||||||
self.ioPins.append( IoPin( *ioPinSpec ) )
|
self.ioPins.append( IoPin( *ioPinSpec ) )
|
||||||
for line in range(len(self.ioPadsArg)):
|
for line in range(len(self.ioPadsArg)):
|
||||||
self.chipConf.addIoPad( self.ioPadsArg[line], line )
|
self.chipConf.addIoPad( self.ioPadsArg[line], line )
|
||||||
|
trace( 550, ',-' )
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def isCoreBlock ( self ): return self.chip is not None
|
def isCoreBlock ( self ): return self.chip is not None
|
||||||
|
|
|
@ -61,6 +61,17 @@ class Chip ( Block ):
|
||||||
self.conf.validated = False
|
self.conf.validated = False
|
||||||
return self.conf.validated
|
return self.conf.validated
|
||||||
|
|
||||||
|
def doChipNetlist ( self ):
|
||||||
|
"""
|
||||||
|
Build the netlist at chip-level around the ``core`` block. Needs the ``conf.coreToChipClass``
|
||||||
|
configuration parameter to be set up. Otherwise assume the netlist is already a chip.
|
||||||
|
"""
|
||||||
|
if not hasattr(self.conf,'coreToChipClass'):
|
||||||
|
print( WarningMessage( 'Chip.doChipNetlist(): No "conf.coreToChipClass" defined, assume we already have a chip-level netlist.' ) )
|
||||||
|
return
|
||||||
|
self.conf.coreToChip = self.conf.coreToChipClass( self.conf )
|
||||||
|
self.conf.coreToChip.buildChip()
|
||||||
|
|
||||||
def doChipFloorplan ( self ):
|
def doChipFloorplan ( self ):
|
||||||
self.padsCorona = None
|
self.padsCorona = None
|
||||||
minHCorona = self.conf.minHCorona
|
minHCorona = self.conf.minHCorona
|
||||||
|
|
|
@ -112,6 +112,7 @@ class ChipConf ( BlockConf ):
|
||||||
self.chipLogos = []
|
self.chipLogos = []
|
||||||
self.minHCorona = 0
|
self.minHCorona = 0
|
||||||
self.minVCorona = 0
|
self.minVCorona = 0
|
||||||
|
self.coreToChip = None
|
||||||
trace( 550, '-' )
|
trace( 550, '-' )
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -149,15 +149,13 @@ class Corner ( object ):
|
||||||
|
|
||||||
def _instanciateCorner ( self ):
|
def _instanciateCorner ( self ):
|
||||||
name, transformation = self._getTransformation()
|
name, transformation = self._getTransformation()
|
||||||
corner = Instance.create( self.conf.chip
|
corner = self.conf.coreToChip.createCorner( name )
|
||||||
, name, self.corona.padCorner
|
corner.setTransformation ( transformation )
|
||||||
, transformation
|
corner.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||||
, Instance.PlacementStatus.FIXED
|
|
||||||
)
|
|
||||||
|
|
||||||
def doLayout ( self ):
|
def doLayout ( self ):
|
||||||
if self.corona.padCorner: self._instanciateCorner()
|
if self.conf.coreToChip.hasCornerCell(): self._instanciateCorner()
|
||||||
else: self._createCorner()
|
else: self._createCorner()
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
@ -261,34 +259,55 @@ class Side ( object ):
|
||||||
return self.conf.validated
|
return self.conf.validated
|
||||||
|
|
||||||
def _fillPadSpacing ( self, gapWidth ):
|
def _fillPadSpacing ( self, gapWidth ):
|
||||||
|
"""
|
||||||
def _getWidth ( spacer ): return spacer.getAbutmentBox().getWidth()
|
Fill ``gapWidth`` with I/O pad spacer (Use widest cells first).
|
||||||
|
"""
|
||||||
def _nextSpacer ( iPadSpacer ):
|
if not self.conf.coreToChip.hasFillerCells():
|
||||||
while iPadSpacer < len(self.corona.padSpacers) \
|
|
||||||
and gapWidth < _getWidth(self.corona.padSpacers[iPadSpacer]):
|
|
||||||
iPadSpacer += 1
|
|
||||||
return iPadSpacer
|
|
||||||
|
|
||||||
if not self.corona.padSpacers:
|
|
||||||
self.u += gapWidth
|
self.u += gapWidth
|
||||||
return
|
return
|
||||||
iPadSpacer = 0
|
|
||||||
iPadSpacer = _nextSpacer( iPadSpacer )
|
while gapWidth > 0:
|
||||||
while iPadSpacer < len(self.corona.padSpacers) and gapWidth > 0:
|
spacer = self.conf.coreToChip.createSpacer( gapWidth )
|
||||||
gapWidth -= _getWidth( self.corona.padSpacers[iPadSpacer] )
|
if not spacer:
|
||||||
spacer = Instance.create( self.conf.chip
|
print( ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads @{} on {} side, {} remains.' \
|
||||||
, self.spacerNames % self.spacerCount
|
.format( DbU.getValueString(self.u)
|
||||||
, self.corona.padSpacers[iPadSpacer])
|
, self.sideName
|
||||||
self.spacerCount += 1
|
, DbU.getValueString(gapWidth) )))
|
||||||
|
break
|
||||||
self._placePad( spacer )
|
self._placePad( spacer )
|
||||||
if gapWidth < _getWidth(self.corona.padSpacers[iPadSpacer]):
|
gapWidth -= spacer.getMasterCell().getAbutmentBox().getWidth()
|
||||||
iPadSpacer = _nextSpacer( iPadSpacer )
|
trace( 550, '\tself.u:{} gapWidth:{} after spacer {}\n'.format( DbU.getValueString(self.u)
|
||||||
if gapWidth != 0:
|
, DbU.getValueString(gapWidth)
|
||||||
print( ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads on {} side, {} remains.' \
|
, spacer ))
|
||||||
.format(self.sideName,DbU.getValueString(gapWidth)) ))
|
|
||||||
self.u += gapWidth
|
self.u += gapWidth
|
||||||
|
|
||||||
|
#def _getWidth ( spacer ): return spacer.getAbutmentBox().getWidth()
|
||||||
|
#
|
||||||
|
#def _nextSpacer ( iPadSpacer ):
|
||||||
|
# while iPadSpacer < len(self.corona.padSpacers) \
|
||||||
|
# and gapWidth < _getWidth(self.corona.padSpacers[iPadSpacer]):
|
||||||
|
# iPadSpacer += 1
|
||||||
|
# return iPadSpacer
|
||||||
|
#
|
||||||
|
#if not self.corona.padSpacers:
|
||||||
|
# self.u += gapWidth
|
||||||
|
# return
|
||||||
|
#iPadSpacer = 0
|
||||||
|
#iPadSpacer = _nextSpacer( iPadSpacer )
|
||||||
|
#while iPadSpacer < len(self.corona.padSpacers) and gapWidth > 0:
|
||||||
|
# gapWidth -= _getWidth( self.corona.padSpacers[iPadSpacer] )
|
||||||
|
# spacer = Instance.create( self.conf.chip
|
||||||
|
# , self.spacerNames % self.spacerCount
|
||||||
|
# , self.corona.padSpacers[iPadSpacer])
|
||||||
|
# self.spacerCount += 1
|
||||||
|
# self._placePad( spacer )
|
||||||
|
# if gapWidth < _getWidth(self.corona.padSpacers[iPadSpacer]):
|
||||||
|
# iPadSpacer = _nextSpacer( iPadSpacer )
|
||||||
|
#if gapWidth != 0:
|
||||||
|
# print( ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads on {} side, {} remains.' \
|
||||||
|
# .format(self.sideName,DbU.getValueString(gapWidth)) ))
|
||||||
|
#self.u += gapWidth
|
||||||
|
|
||||||
def _placePad ( self, padInstance ):
|
def _placePad ( self, padInstance ):
|
||||||
padAb = padInstance.getMasterCell().getAbutmentBox()
|
padAb = padInstance.getMasterCell().getAbutmentBox()
|
||||||
if self.type == North:
|
if self.type == North:
|
||||||
|
@ -401,7 +420,10 @@ class Side ( object ):
|
||||||
for pad in self.pads:
|
for pad in self.pads:
|
||||||
self._fillPadSpacing( pad[0] - self.u )
|
self._fillPadSpacing( pad[0] - self.u )
|
||||||
self._placePad( pad[1] )
|
self._placePad( pad[1] )
|
||||||
self._fillPadSpacing( self.sideLength - self.conf.ioPadHeight - self.u )
|
cornerWidth = self.conf.ioPadHeight
|
||||||
|
if self.conf.coreToChip.hasCornerCell():
|
||||||
|
cornerWidth = self.conf.coreToChip.getCornerCell().getAbutmentBox().getWidth()
|
||||||
|
self._fillPadSpacing( self.sideLength - cornerWidth - self.u )
|
||||||
|
|
||||||
def _getUMin ( self, box ):
|
def _getUMin ( self, box ):
|
||||||
if self.type == North or self.type == South:
|
if self.type == North or self.type == South:
|
||||||
|
|
|
@ -259,6 +259,9 @@ class IoPad ( object ):
|
||||||
TRI_OUT = 0x0008
|
TRI_OUT = 0x0008
|
||||||
ANALOG = 0x0010
|
ANALOG = 0x0010
|
||||||
UNSUPPORTED = 0x0020
|
UNSUPPORTED = 0x0020
|
||||||
|
FILLER = 0x0040
|
||||||
|
CORNER = 0x0080
|
||||||
|
NON_CONNECT = 0x0100
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def directionToStr ( direction ):
|
def directionToStr ( direction ):
|
||||||
|
@ -268,12 +271,13 @@ class IoPad ( object ):
|
||||||
if direction == IoPad.TRI_OUT: return "TRI_OUT"
|
if direction == IoPad.TRI_OUT: return "TRI_OUT"
|
||||||
if direction == IoPad.ANALOG: return "ANALOG"
|
if direction == IoPad.ANALOG: return "ANALOG"
|
||||||
if direction == IoPad.UNSUPPORTED: return "UNSUPPORTED"
|
if direction == IoPad.UNSUPPORTED: return "UNSUPPORTED"
|
||||||
|
if direction == IoPad.NON_CONNECT: return "NON_CONNECT"
|
||||||
return "Invalid value"
|
return "Invalid value"
|
||||||
|
|
||||||
def __init__ ( self, coreToChip, ioPadConf ):
|
def __init__ ( self, coreToChip, ioPadConf ):
|
||||||
self.coreToChip = coreToChip
|
self.coreToChip = coreToChip
|
||||||
self.ioPadConf = ioPadConf
|
self.ioPadConf = ioPadConf
|
||||||
self.direction = 0
|
self.direction = IoPad.NON_CONNECT
|
||||||
self.nets = []
|
self.nets = []
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -361,6 +365,8 @@ class IoPad ( object ):
|
||||||
self.nets[0].buildNets()
|
self.nets[0].buildNets()
|
||||||
connexions.append( ( self.nets[0].chipExtNet, padInfo.padNet ) )
|
connexions.append( ( self.nets[0].chipExtNet, padInfo.padNet ) )
|
||||||
connexions.append( ( self.nets[0].chipIntNet, padInfo.coreNets[1] ) )
|
connexions.append( ( self.nets[0].chipIntNet, padInfo.coreNets[1] ) )
|
||||||
|
elif (self.direction == IoPad.NON_CONNECT):
|
||||||
|
pass
|
||||||
elif (self.direction == IoPad.BIDIR) and (len(self.nets) < 3):
|
elif (self.direction == IoPad.BIDIR) and (len(self.nets) < 3):
|
||||||
# Case of BIDIR as fallback for simple IN/OUT.
|
# Case of BIDIR as fallback for simple IN/OUT.
|
||||||
self.nets[0].setFlags( IoNet.DoExtNet )
|
self.nets[0].setFlags( IoNet.DoExtNet )
|
||||||
|
@ -517,7 +523,7 @@ class CoreToChip ( object ):
|
||||||
.format( core.getName() )
|
.format( core.getName() )
|
||||||
] )
|
] )
|
||||||
conf = block.state
|
conf = block.state
|
||||||
conf._postInit()
|
#conf._postInit()
|
||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.conf.useHarness = False
|
self.conf.useHarness = False
|
||||||
self.ringNetNames = []
|
self.ringNetNames = []
|
||||||
|
@ -668,6 +674,26 @@ class CoreToChip ( object ):
|
||||||
"""Load the DEF file containing the reference harness layout."""
|
"""Load the DEF file containing the reference harness layout."""
|
||||||
raise NotImplementedError( 'coreToChip._loadHarness(): This method must be overloaded.' )
|
raise NotImplementedError( 'coreToChip._loadHarness(): This method must be overloaded.' )
|
||||||
|
|
||||||
|
def hasCornerCell ( self ):
|
||||||
|
"""Is there a special cell for corners. This method may be overloaded."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def hasFillerCells ( self ):
|
||||||
|
"""Is there a special cell(s) for filling gaps. This method may be overloaded."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getCornerCell ( self, instanceName=None ):
|
||||||
|
"""Return the model of corner cell."""
|
||||||
|
raise NotImplementedError( 'coreToChip.getCornerCell(): This method must be overloaded.' )
|
||||||
|
|
||||||
|
def createSpacer ( self, gapWidth ):
|
||||||
|
"""Return a new instance of spacer cell."""
|
||||||
|
raise NotImplementedError( 'coreToChip.createSpacer(): This method must be overloaded.' )
|
||||||
|
|
||||||
|
def createCorner ( self ):
|
||||||
|
"""Return a new instance of corner cell."""
|
||||||
|
raise NotImplementedError( 'coreToChip.createCorner(): This method must be overloaded' )
|
||||||
|
|
||||||
def buildChip ( self ):
|
def buildChip ( self ):
|
||||||
"""
|
"""
|
||||||
Build the whole chip+corona hierarchical structure (netlist only)
|
Build the whole chip+corona hierarchical structure (netlist only)
|
||||||
|
|
|
@ -59,13 +59,13 @@ Pad* Pad::create(Net* net, const Layer* layer, const Box& boundingBox)
|
||||||
DbU::Unit Pad::getX() const
|
DbU::Unit Pad::getX() const
|
||||||
// *******************
|
// *******************
|
||||||
{
|
{
|
||||||
return 0;
|
return _boundingBox.getXCenter();
|
||||||
}
|
}
|
||||||
|
|
||||||
DbU::Unit Pad::getY() const
|
DbU::Unit Pad::getY() const
|
||||||
// *******************
|
// *******************
|
||||||
{
|
{
|
||||||
return 0;
|
return _boundingBox.getYCenter();
|
||||||
}
|
}
|
||||||
|
|
||||||
Box Pad::getBoundingBox() const
|
Box Pad::getBoundingBox() const
|
||||||
|
|
|
@ -377,19 +377,23 @@ namespace Hurricane {
|
||||||
double bestArea = getArea(bestComponent);
|
double bestArea = getArea(bestComponent);
|
||||||
|
|
||||||
if (compArea == bestArea) {
|
if (compArea == bestArea) {
|
||||||
Box compBox = component->getBoundingBox();
|
if (dynamic_cast<Segment*>(component) and dynamic_cast<Pad*>(bestComponent)) {
|
||||||
Box bestBox = bestComponent->getBoundingBox();
|
bestComponent = component;
|
||||||
|
|
||||||
if (compBox.getXMin() == bestBox.getXMin()) {
|
|
||||||
if (compBox.getYMin() == bestBox.getYMin()) {
|
|
||||||
if (component->getId() < bestComponent->getId())
|
|
||||||
bestComponent = component;
|
|
||||||
} else
|
|
||||||
if (compBox.getYMin() < bestBox.getYMin())
|
|
||||||
bestComponent = component;
|
|
||||||
} else {
|
} else {
|
||||||
if (compBox.getXMin() < bestBox.getXMin())
|
Box compBox = component->getBoundingBox();
|
||||||
bestComponent = component;
|
Box bestBox = bestComponent->getBoundingBox();
|
||||||
|
|
||||||
|
if (compBox.getXMin() == bestBox.getXMin()) {
|
||||||
|
if (compBox.getYMin() == bestBox.getYMin()) {
|
||||||
|
if (component->getId() < bestComponent->getId())
|
||||||
|
bestComponent = component;
|
||||||
|
} else
|
||||||
|
if (compBox.getYMin() < bestBox.getYMin())
|
||||||
|
bestComponent = component;
|
||||||
|
} else {
|
||||||
|
if (compBox.getXMin() < bestBox.getXMin())
|
||||||
|
bestComponent = component;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (compArea > bestArea)
|
if (compArea > bestArea)
|
||||||
|
|
Loading…
Reference in New Issue