Improve the management of the I/O pad near the chip corner.

* Bug: In cumulus/plugins/PadsCorona.py, when a pad is at the beginning
    or at the end of the side, the pad corona terminal may be outside
    the corona range (not directly facing it). In that case, create a
    bend to reach it.
      Worse, in some case more than one (but likely no more), could be
    in that case, so not only do we create a bend but also make a
    shift in the bended segment so two consecutive ones are not on the
    same axis, causing shorts.
      If both end pads of a corner are in that case, we cannot prevent
    a short, so at least, issue a warning.
* Bug: In CRL::Vhdl, the Entity::VstUseConcat was not passed correctly
    along, so we did get a strange mix of conat and direct assignment.
* New: In Unicorn/cgt.py : added --vst-use-concat options to control
    the VST driver behavior.
This commit is contained in:
Jean-Paul Chaput 2019-08-16 00:40:49 +02:00
parent f92b48174b
commit 91f973c00f
10 changed files with 385 additions and 69 deletions

View File

@ -195,6 +195,34 @@ namespace CRL {
}
DbU::Unit RoutingGauge::getPitch ( const Layer* layer ) const
{
size_t depth = getLayerDepth( layer );
return (depth != nlayerdepth) ? _layerGauges[depth]->getPitch() : 0;
}
DbU::Unit RoutingGauge::getOffset ( const Layer* layer ) const
{
size_t depth = getLayerDepth( layer );
return (depth != nlayerdepth) ? _layerGauges[depth]->getOffset() : 0;
}
DbU::Unit RoutingGauge::getWireWidth ( const Layer* layer ) const
{
size_t depth = getLayerDepth( layer );
return (depth != nlayerdepth) ? _layerGauges[depth]->getWireWidth() : 0;
}
DbU::Unit RoutingGauge::getViaWidth ( const Layer* layer ) const
{
size_t depth = getLayerDepth( layer );
return (depth != nlayerdepth) ? _layerGauges[depth]->getViaWidth() : 0;
}
RoutingLayerGauge* RoutingGauge::getLayerGauge ( size_t depth ) const
{
if ( depth >= _layerGauges.size() ) return NULL;

View File

@ -110,7 +110,7 @@ namespace Vhdl {
_offset = (ptrdiff_t)this - (ptrdiff_t)property;
}
if (_flags == NoFlags) _flags = EntityMode;
if ((_flags & ~ModeMask) == NoFlags) _flags |= EntityMode;
for ( Net* net : cell->getNets() ) {
if (net->isDeepNet()) continue;
@ -353,7 +353,8 @@ namespace Vhdl {
}
for ( auto icell : masterCells ) {
Vhdl::Entity* component = Vhdl::EntityExtension::create( icell, Vhdl::Entity::ComponentMode );
Vhdl::Entity* component = Vhdl::EntityExtension::create
( icell, Vhdl::Entity::ComponentMode | (_flags & ModeMask));
component->toComponent( out );
out << "\n";
}
@ -393,7 +394,8 @@ namespace Vhdl {
Entity* masterEntity = EntityExtension::get( instance->getMasterCell() );
if (not masterEntity) {
masterEntity = EntityExtension::create( instance->getMasterCell(), ComponentMode );
masterEntity = EntityExtension::create
( instance->getMasterCell(), ComponentMode | (_flags & ModeMask));
}
size_t width = 0;

View File

@ -243,6 +243,9 @@ namespace Vhdl {
first = false;
}
} else {
cerr << "VhdlPortMap is in bit mode for \"" << _signal->getName() << "\""
<< " _flags:" << _flags << " mappedNames:" << _mapping.size() << endl;
auto imapping = _mapping.rbegin();
bool first = true;
for ( ; imapping!=_mapping.rend() ; ++imapping ) {

View File

@ -39,7 +39,7 @@ namespace CRL {
void vstDriver ( const string cellPath, Cell *cell, unsigned int& saveState )
{
unsigned int entityFlags = Vhdl::Entity::EntityMode /* | Vhdl::Entity::IeeeMode */;
if (saveState & Catalog::State::VstUseConcat) entityFlags |= Vhdl::Entity::VstUseConcat;
/*if (saveState & Catalog::State::VstUseConcat)*/ entityFlags |= Vhdl::Entity::VstUseConcat;
//NamingScheme::toVhdl( cell, NamingScheme::FromVerilog );
Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, entityFlags );

View File

@ -72,6 +72,10 @@ namespace CRL {
size_t getLayerDepth ( const Layer* ) const;
unsigned int getLayerType ( const Layer* ) const;
unsigned int getLayerDirection ( const Layer* ) const;
DbU::Unit getPitch ( const Layer* ) const;
DbU::Unit getOffset ( const Layer* ) const;
DbU::Unit getWireWidth ( const Layer* ) const;
DbU::Unit getViaWidth ( const Layer* ) const;
RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
inline unsigned int getLayerDirection ( size_t depth ) const;
inline unsigned int getLayerType ( size_t depth ) const;

View File

@ -66,6 +66,7 @@ namespace Vhdl {
, AsInnerSignal = 0x0010
, VstUseConcat = 0x0020
};
const unsigned int ModeMask = VstUseConcat;
public:
static std::vector<Entity*>&
getAllEntities ();

View File

@ -179,6 +179,102 @@ extern "C" {
}
static PyObject* PyRoutingGauge_getPitch ( PyRoutingGauge* self, PyObject* args )
{
cdebug_log(30,0) << "PyRoutingGauge_getPitch()" << endl;
DbU::Unit pitch = 0;
HTRY
METHOD_HEAD("RoutingGauge.getPitch()")
PyObject* pyLayer = NULL;
if (PyArg_ParseTuple( args, "O:RoutingGauge.getPitch", &pyLayer)) {
if ( not PyObject_IsInstance(pyLayer,(PyObject*)&PyTypeLayer) ) {
PyErr_SetString ( ConstructorError, "Bad type for layer argument of RoutingGauge.getLayerPitch()." );
return NULL;
}
pitch = rg->getPitch( PYLAYER_O(pyLayer) );
} else {
PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingGauge.getPitch()." );
return NULL;
}
HCATCH
return Py_BuildValue("I",pitch);
}
static PyObject* PyRoutingGauge_getOffset ( PyRoutingGauge* self, PyObject* args )
{
cdebug_log(30,0) << "PyRoutingGauge_getOffset()" << endl;
DbU::Unit offset = 0;
HTRY
METHOD_HEAD("RoutingGauge.getOffset()")
PyObject* pyLayer = NULL;
if (PyArg_ParseTuple( args, "O:RoutingGauge.getOffset", &pyLayer)) {
if ( not PyObject_IsInstance(pyLayer,(PyObject*)&PyTypeLayer) ) {
PyErr_SetString ( ConstructorError, "Bad type for layer argument of RoutingGauge.getOffset()." );
return NULL;
}
offset = rg->getOffset( PYLAYER_O(pyLayer) );
} else {
PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingGauge.getOffset()." );
return NULL;
}
HCATCH
return Py_BuildValue("I",offset);
}
static PyObject* PyRoutingGauge_getWireWidth ( PyRoutingGauge* self, PyObject* args )
{
cdebug_log(30,0) << "PyRoutingGauge_getWireWidth()" << endl;
DbU::Unit wireWidth = 0;
HTRY
METHOD_HEAD("RoutingGauge.getWireWidth()")
PyObject* pyLayer = NULL;
if (PyArg_ParseTuple( args, "O:RoutingGauge.getWireWidth", &pyLayer)) {
if ( not PyObject_IsInstance(pyLayer,(PyObject*)&PyTypeLayer) ) {
PyErr_SetString ( ConstructorError, "Bad type for layer argument of RoutingGauge.getWireWidth()." );
return NULL;
}
wireWidth = rg->getWireWidth( PYLAYER_O(pyLayer) );
} else {
PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingGauge.getWireWidth()." );
return NULL;
}
HCATCH
return Py_BuildValue("I",wireWidth);
}
static PyObject* PyRoutingGauge_getViaWidth ( PyRoutingGauge* self, PyObject* args )
{
cdebug_log(30,0) << "PyRoutingGauge_getViaWidth()" << endl;
DbU::Unit pitch = 0;
HTRY
METHOD_HEAD("RoutingGauge.getViaWidth()")
PyObject* pyLayer = NULL;
if (PyArg_ParseTuple( args, "O:RoutingGauge.getViaWidth", &pyLayer)) {
if ( not PyObject_IsInstance(pyLayer,(PyObject*)&PyTypeLayer) ) {
PyErr_SetString ( ConstructorError, "Bad type for layer argument of RoutingGauge.getViaWidth()." );
return NULL;
}
pitch = rg->getViaWidth( PYLAYER_O(pyLayer) );
} else {
PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingGauge.getViaWidth()." );
return NULL;
}
HCATCH
return Py_BuildValue("I",pitch);
}
static PyObject* PyRoutingGauge_getLayerGauge ( PyRoutingGauge* self, PyObject* args )
{
cdebug_log(30,0) << "PyRoutingGauge_getLayerGauge()" << endl;
@ -394,6 +490,14 @@ extern "C" {
, "Return the vertical pitch of the metal closest to the substrate." }
, { "getLayerDepth" , (PyCFunction)PyRoutingGauge_getLayerDepth , METH_VARARGS
, "Return the depth of the given layer." }
, { "getPitch" , (PyCFunction)PyRoutingGauge_getPitch , METH_VARARGS
, "Return the routing pitch of the given layer." }
, { "getOffset" , (PyCFunction)PyRoutingGauge_getOffset , METH_VARARGS
, "Return the offset of the first track of the given layer." }
, { "getWireWidth" , (PyCFunction)PyRoutingGauge_getWireWidth , METH_VARARGS
, "Return the default wire width of the given layer." }
, { "getViaWidth" , (PyCFunction)PyRoutingGauge_getViaWidth , METH_VARARGS
, "Return the default via width of the given layer." }
, { "getLayerGauge" , (PyCFunction)PyRoutingGauge_getLayerGauge , METH_VARARGS
, "Return the RoutingLayerGauge of the given layer/depth." }
, { "getLayerDirection" , (PyCFunction)PyRoutingGauge_getLayerDirection , METH_VARARGS

View File

@ -216,6 +216,7 @@ class GaugeConf ( object ):
def getIoPadGauge ( self ): return self.ioPadGauge
def getHRoutingGauge ( self ): return self.routingGauge.getLayerGauge( self.horizontalDepth )
def getVRoutingGauge ( self ): return self.routingGauge.getLayerGauge( self.verticalDepth )
def getPitch ( self, layer ): return self.routingGauge.getPitch( layer )
def _loadRoutingGauge ( self ):
gaugeName = Cfg.getParamString('anabatic.routingGauge').asString()
@ -734,6 +735,45 @@ class ChipConf ( object ):
return axis, width
def toCoronaPitchInChip ( self, uCore, layer ):
trace( 550, ',+', '\tChipConf.toCoronaPitchInChip(): uCore: %sl %s\n' % (DbU.toLambda(uCore), DbU.getValueString(uCore)) )
coronaAb = self.getInstanceAb( self.icorona )
lg = None
mask = layer.getMask()
for layerGauge in self.gaugeConf.routingGauge.getLayerGauges():
if layerGauge.getLayer().getMask() == mask:
lg = layerGauge
break
if not lg:
trace( 550, '-' )
return 0
trace( 550, '\t%s\n' % str(lg) )
if lg:
if lg.getDirection() == RoutingLayerGauge.Horizontal:
uCorona = uCore - coronaAb.getYMin()
else:
uCorona = uCore - coronaAb.getXMin()
uCorona, width = self.toRoutingGauge( uCorona, uCorona, layer )
trace( 550, '\ttoCoronaPitchInChip(): uCorona: %sl %s\n' % (DbU.toLambda(uCorona), DbU.getValueString(uCorona)) )
if lg:
if lg.getDirection() == RoutingLayerGauge.Horizontal:
uCore = uCorona + coronaAb.getYMin()
else:
uCore = uCorona + coronaAb.getXMin()
trace( 550, '\ttoCoronaPitchInChip(): uCorona: %sl %s\n' % (DbU.toLambda(uCorona), DbU.getValueString(uCorona)) )
trace( 550, '\ttoCoronaPitchInChip(): uCore: %sl %s\n' % (DbU.toLambda(uCore ), DbU.getValueString(uCore )) )
trace( 550, '-' )
return uCore
def coronaHorizontal ( self, chipNet, layer, chipY, width, chipXMin, chipXMax ):
trace( 550, ',+', '\tChipConf.coronaHorizontal\n' )
@ -958,7 +998,7 @@ class ChipConf ( object ):
if padList[i][1] == padInstance.getName():
if (padInstance.getMasterCell().getAbutmentBox().getHeight() != self.gaugeConf.getIoPadHeight()):
raise ErrorMessage( 1, 'The pad [%d] %s (%s) on %s side is not an instance of a pad cell.'
% (i,padInstance.getName(),padInstance.getModel().getName(),side) )
% (i,padInstance.getName(),padInstance.getMasterCell().getName(),side) )
padList[i][1] = padInstance
return True
return False

View File

@ -169,6 +169,7 @@ class Side ( object ):
self.u = self.conf.getIoPadHeight()
self.spacerCount = 0
self.gap = 0
self.coreWires = []
if self.type == chip.North:
self.pads = self.conf.northPads
@ -221,6 +222,16 @@ class Side ( object ):
return False
def addCoreWire ( self, coreWire ):
self.coreWires.append( coreWire )
return
def updateGap ( self, gapWidth ):
self.gap = max( self.gap, gapWidth )
return
def _check ( self, checkSize, checkName ):
sideName = 'unknown'
chipSize = 0
@ -552,20 +563,75 @@ class Side ( object ):
return
def drawCoreWires ( self ):
trace( 550, ',+', '\tSide.drawCoreWire()\n' )
if self.type == chip.West or self.type == chip.East:
trace( 550, 'Sort East/West' )
self.coreWires.sort( key=lambda wire: wire.bbSegment.getCenter().getY() )
if self.type == chip.North or self.type == chip.South:
trace( 550, 'Sort North/South' )
self.coreWires.sort( key=lambda wire: wire.bbSegment.getCenter().getX() )
for wire in self.coreWires:
wire.updateInCorona()
size = len(self.coreWires)
offset = 0
for i in range(size):
if self.coreWires[i].inCoronaRange: break
offset += 1
for i in range(offset):
self.coreWires[i].setOffset( i+1, CoreWire.AtBegin )
offset = 0
for i in range(1,size+1):
if self.coreWires[-i].inCoronaRange: break
offset += 1
for i in range(offset):
self.coreWires[ -(offset+1) ].setOffset( i+1, CoreWire.AtEnd )
for wire in self.coreWires:
if self.type == chip.West or self.type == chip.East:
trace( 550, '\t| %s %s %d %s inRange:%s\n' % ( wire.chipNet.getName()
, DbU.getValueString(wire.bbSegment.getCenter().getY())
, wire.count
, wire.padSegment.getLayer()
, wire.inCoronaRange ) )
if self.type == chip.North or self.type == chip.South:
trace( 550, '\t| %s %s %d %s inRange:%s\n' % ( wire.chipNet.getName()
, DbU.getValueString(wire.bbSegment.getCenter().getX())
, wire.count
, wire.padSegment.getLayer()
, wire.inCoronaRange ) )
wire.drawWire()
trace( 550, '-' )
return
class CoreWire ( object ):
# Should be read from the symbolic technology rules.
viaPitch = DbU.fromLambda( 4.0 )
NoOffset = 0x0000
AtBegin = 0x0001
AtEnd = 0x0002
def __init__ ( self, corona, chipNet, padSegment, bbSegment, side, preferredDir, count ):
self.corona = corona
self.chipNet = chipNet
self.padSegment = padSegment
self.bbSegment = bbSegment
self.side = side
self.preferredDir = preferredDir
self.arraySize = None
self.count = count
self.corona = corona
self.chipNet = chipNet
self.padSegment = padSegment
self.bbSegment = bbSegment
self.offset = 0
self.offsetType = CoreWire.NoOffset
self.side = side
self.preferredDir = preferredDir
self.inCoronaRange = True
self.arraySize = None
self.count = count
return
@ -573,6 +639,27 @@ class CoreWire ( object ):
def conf ( self ): return self.corona.conf
def updateInCorona ( self ):
coronaAb = self.conf.getInstanceAb( self.conf.icorona )
if self.side == chip.South or self.side == chip.North:
xCoronaPin = self.bbSegment.getCenter().getX()
if xCoronaPin <= coronaAb.getXMin(): self.inCoronaRange = False
elif xCoronaPin >= coronaAb.getXMax(): self.inCoronaRange = False
if self.side == chip.East or self.side == chip.West:
yCoronaPin = self.bbSegment.getCenter().getY()
if yCoronaPin <= coronaAb.getYMin(): self.inCoronaRange = False
elif yCoronaPin >= coronaAb.getYMax(): self.inCoronaRange = False
return
def setOffset ( self, offset, offsetType ):
self.offset = offset
self.offsetType = offsetType
def _computeCoreLayers ( self ):
rg = self.conf.gaugeConf.routingGauge
mask = self.padSegment.getLayer().getMask()
@ -627,7 +714,7 @@ class CoreWire ( object ):
def drawWire ( self ):
trace( 550, ',+', '\tCoreWire.drawWire(): chip:"%s"\n' %(self.chipNet.getName()) )
coreAb = self.conf.getInstanceAb( self.conf.icorona )
coronaAb = self.conf.getInstanceAb( self.conf.icorona )
self._computeCoreLayers()
@ -637,21 +724,30 @@ class CoreWire ( object ):
if self.side == chip.West or self.side == chip.East:
flags = chip.OnHorizontalPitch
hPitch = self.conf.gaugeConf.getPitch( self.symSegmentLayer )
vPitch = self.conf.gaugeConf.getPitch( self.padSegment.getLayer() )
yCore = self.conf.toCoronaPitchInChip( self.bbSegment.getCenter().getY(), self.symSegmentLayer )
if self.offset:
if self.offsetType == CoreWire.AtBegin:
yCore += 2*hPitch*self.offset
else:
yCore -= 2*hPitch*self.offset
if self.side == chip.West:
accessDirection = Pin.Direction.WEST
xPadMin = self.bbSegment.getXMin()
xContact = self.corona.coreSymBb.getXMin()
xContact = self.corona.coreSymBb.getXMin() - self.offset * 2*vPitch
xPadMax = xContact
xCore = coreAb.getXMin()
xCore = coronaAb.getXMin()
if not self.preferredDir:
xPadMax += self.bbSegment.getHeight()/2
else:
accessDirection = Pin.Direction.EAST
xPadMax = self.bbSegment.getXMax()
xContact = self.corona.coreSymBb.getXMax()
xContact = self.corona.coreSymBb.getXMax() + self.offset * 2*vPitch
xPadMin = xContact
xCore = coreAb.getXMax()
xCore = coronaAb.getXMax()
if not self.preferredDir:
xPadMin -= self.bbSegment.getHeight()/2
@ -665,24 +761,24 @@ class CoreWire ( object ):
trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) )
if self.arraySize:
contacts = self.conf.coronaContactArray( self.chipNet
, self.symContactLayer
, xContact
, self.bbSegment.getCenter().getY()
, self.arraySize
, flags
)
, self.symContactLayer
, xContact
, yCore
, self.arraySize
, flags
)
vStrapBb = Box()
for contact in contacts:
vStrapBb.merge( contact.getBoundingBox() )
else:
contact = self.conf.coronaContact( self.chipNet
, self.symContactLayer
, xContact
, self.bbSegment.getCenter().getY()
, self.symContactSize[0]
, self.symContactSize[1]
, flags
)
, self.symContactLayer
, xContact
, yCore
, self.symContactSize[0]
, self.symContactSize[1]
, flags
)
vStrapBb = contact.getBoundingBox( padLayer )
hRealBb = hReal.getBoundingBox( padLayer )
@ -707,7 +803,7 @@ class CoreWire ( object ):
self.conf.coronaHorizontal( self.chipNet
, self.symSegmentLayer
, self.bbSegment.getCenter().getY()
, yCore
, self.bbSegment.getHeight()
, xContact
, xCore
@ -718,27 +814,38 @@ class CoreWire ( object ):
, accessDirection
, self.symSegmentLayer
, xCore
, self.bbSegment.getCenter().getY()
, yCore
, DbU.fromLambda( 1.0 )
, self.bbSegment.getHeight()
)
else:
flags = chip.OnVerticalPitch
flags = chip.OnVerticalPitch
hPitch = self.conf.gaugeConf.getPitch( self.padSegment.getLayer() )
vPitch = self.conf.gaugeConf.getPitch( self.symSegmentLayer )
trace( 550, '\t%s translated of %s\n' % (self.symSegmentLayer, DbU.getValueString( 2*vPitch*self.offset )) )
xCore = self.conf.toCoronaPitchInChip( self.bbSegment.getCenter().getX(), self.symSegmentLayer )
if self.offset:
if self.offsetType == CoreWire.AtBegin:
xCore += 2*vPitch*self.offset
else:
xCore -= 2*vPitch*self.offset
if self.side == chip.South:
accessDirection = Pin.Direction.SOUTH
yPadMin = self.bbSegment.getYMin()
yPadMax = self.corona.coreSymBb.getYMin()
yPadMax = self.corona.coreSymBb.getYMin() - self.offset * 2*hPitch
yContact = yPadMax
yCore = coreAb.getYMin()
yCore = coronaAb.getYMin()
if not self.preferredDir:
yPadMax += self.bbSegment.getWidth()/2
else:
accessDirection = Pin.Direction.NORTH
yPadMax = self.bbSegment.getYMax()
yPadMin = self.corona.coreSymBb.getYMax()
yPadMin = self.corona.coreSymBb.getYMax() + self.offset * 2*hPitch
yContact = yPadMin
yCore = coreAb.getYMax()
yCore = coronaAb.getYMax()
if not self.preferredDir:
yPadMin -= self.bbSegment.getWidth()/2
@ -753,7 +860,7 @@ class CoreWire ( object ):
if self.arraySize:
contacts = self.conf.coronaContactArray( self.chipNet
, self.symContactLayer
, self.bbSegment.getCenter().getX()
, xCore
, yContact
, self.arraySize
, flags
@ -792,9 +899,10 @@ class CoreWire ( object ):
if self.side == chip.South: yContact = min( yContact, hStrapBb.getYMin() )
else: yContact = max( yContact, hStrapBb.getYMax() )
trace( 550, '\txCore: %sl %s\n' % (DbU.toLambda(xCore), DbU.getValueString(xCore)) )
self.conf.coronaVertical( self.chipNet
, self.symSegmentLayer
, self.bbSegment.getCenter().getX()
, xCore
, self.bbSegment.getWidth()
, yContact
, yCore
@ -803,7 +911,7 @@ class CoreWire ( object ):
, self.count
, accessDirection
, self.symSegmentLayer
, self.bbSegment.getCenter().getX()
, xCore
, yCore
, self.bbSegment.getWidth()
, DbU.fromLambda( 1.0 )
@ -967,12 +1075,12 @@ class Corona ( object ):
def _createCoreWire ( self, chipIntNet, padNet, padInstance, count ):
padSide = None
if self.hasSouthPad(padInstance): padSide = chip.South
elif self.hasNorthPad(padInstance): padSide = chip.North
elif self.hasEastPad (padInstance): padSide = chip.East
elif self.hasWestPad (padInstance): padSide = chip.West
if not padSide: return None
side = None
if self.hasSouthPad(padInstance): side = self.southSide
elif self.hasNorthPad(padInstance): side = self.northSide
elif self.hasEastPad (padInstance): side = self.eastSide
elif self.hasWestPad (padInstance): side = self.westSide
if not side: return count
innerBb = self.conf.cell.getAbutmentBox().inflate( -self.conf.getIoPadHeight() )
rg = self.conf.gaugeConf.routingGauge
@ -1005,7 +1113,7 @@ class Corona ( object ):
gapWidth = 0
segments = None
inPreferredDir = False
if padSide == chip.North or padSide == chip.South:
if side.type == chip.North or side.type == chip.South:
if len(vsegments):
inPreferredDir = True
segments = vsegments[ min(vsegments.keys()) ]
@ -1025,14 +1133,10 @@ class Corona ( object ):
coreWires = []
if segments:
for segment, bb in segments:
if padSide == chip.South: self.southSide.gap = max( self.southSide.gap, gapWidth )
elif padSide == chip.North: self.northSide.gap = max( self.northSide.gap, gapWidth )
elif padSide == chip.East : self.eastSide.gap = max( self.eastSide.gap , gapWidth )
elif padSide == chip.West : self.westSide.gap = max( self.westSide.gap , gapWidth )
coreWires.append( CoreWire( self, chipIntNet, segment, bb, padSide, inPreferredDir, count ) )
side.updateGap ( gapWidth )
side.addCoreWire( CoreWire( self, chipIntNet, segment, bb, side.type, inPreferredDir, count ) )
count += 1
return coreWires
return count
def _placeInnerCorona ( self ):
@ -1045,8 +1149,6 @@ class Corona ( object ):
self.eastSide.gap = self.southSide.gap
self.westSide.gap = self.southSide.gap
coreWires = []
for coronaPlug in self.conf.icorona.getPlugs():
chipIntNet = coronaPlug.getNet()
if not chipIntNet:
@ -1058,11 +1160,8 @@ class Corona ( object ):
doneInstances = []
for chipPlug in chipIntNet.getPlugs():
doneInstances.append( chipPlug.getInstance() )
padNet = chipPlug.getMasterNet()
padWires = self._createCoreWire( chipIntNet, padNet, doneInstances[-1], padConnected )
if padWires:
coreWires += padWires
padConnected += len(padWires)
padNet = chipPlug.getMasterNet()
padConnected = self._createCoreWire( chipIntNet, padNet, doneInstances[-1], padConnected )
if chipIntNet.isGlobal():
for instance in self.conf.cell.getInstances():
@ -1072,10 +1171,7 @@ class Corona ( object ):
padNet = instance.getMasterCell().getNet( chipIntNet.getName() )
if not padNet: continue
padWires = self._createCoreWire( chipIntNet, padNet, doneInstances[-1], padConnected )
if padWires:
coreWires += padWires
padConnected += len(padWires)
padConnected = self._createCoreWire( chipIntNet, padNet, doneInstances[-1], padConnected )
if padConnected == 0:
raise ErrorMessage( 1, 'PadsCorona._placeInnerCorona(): Chip net "%s" is not connected to a pad.' \
@ -1089,10 +1185,46 @@ class Corona ( object ):
, self.conf.toSymbolic( self.eastSide.gap /2, chip.Inferior )
, self.conf.toSymbolic( self.northSide.gap/2, chip.Inferior ) )
for wire in coreWires:
trace( 550, '\t| %s %d %s\n' % (wire.chipNet.getName(),wire.count,wire.padSegment.getLayer()))
self.southSide.drawCoreWires()
self.northSide.drawCoreWires()
self.eastSide .drawCoreWires()
self.westSide .drawCoreWires()
for wire in coreWires: wire.drawWire()
if len(self.southSide.coreWires) \
and len(self.westSide .coreWires) \
and not self.southSide.coreWires[0].inCoronaRange \
and not self.westSide .coreWires[0].inCoronaRange:
print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on south-east corner are outside corona range.'
, 'This will generate a short-circuit between S:"%s" and W:"%s".' % \
( self.southSide.coreWires[0].chipNet.getName()
, self.westSide .coreWires[0].chipNet.getName()) ] )
if len(self.southSide.coreWires) \
and len(self.eastSide .coreWires) \
and not self.southSide.coreWires[-1].inCoronaRange \
and not self.eastSide .coreWires[ 0].inCoronaRange:
print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on south-west corner are outside corona range.'
, 'This will generate a short-circuit between S:"%s" and E:"%s.' % \
( self.southSide.coreWires[-1].chipNet.getName()
, self.eastSide .coreWires[ 0].chipNet.getName()) ] )
if len(self.northSide.coreWires) \
and len(self.westSide .coreWires) \
and not self.northSide.coreWires[ 0].inCoronaRange \
and not self.westSide .coreWires[-1].inCoronaRange:
print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on north-east corner are outside corona range.'
, 'This will generate a short-circuit between N:"%s" and W:"%s".' % \
( self.northSide.coreWires[ 0].chipNet.getName()
, self.westSide .coreWires[-1].chipNet.getName()) ] )
if len(self.northSide.coreWires) \
and len(self.eastSide .coreWires) \
and not self.northSide.coreWires[-1].inCoronaRange \
and not self.eastSide .coreWires[-1].inCoronaRange:
print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on north-west corner are outside corona range.'
, 'This will generate a short-circuit between N:"%s" and E:"%s.' % \
( self.northSide.coreWires[-1].chipNet.getName()
, self.eastSide .coreWires[-1].chipNet.getName()) ] )
return

View File

@ -129,6 +129,7 @@ if __name__ == '__main__':
parser.add_option( '-M', '--dump-measures' , action='store_true', dest='dumpMeasures' , help='Dump some statistical measurements on the disk.')
parser.add_option( '-s', '--save-design' , type='string' , dest='saveDesign' , help='Save the routed design.')
parser.add_option( '--top-routing-layer', type='string' , dest='topRoutingLayer', help='Sets the top (upper) routing layer.')
parser.add_option( '--vst-use-concat' , action='store_true', dest='vstUseConcat' , help='The VST driver will use "&" (concat) in PORT MAP.')
(options, args) = parser.parse_args()
args.insert(0, 'cgt')
@ -260,6 +261,7 @@ if __name__ == '__main__':
if options.saveDesign:
views = CRL.Catalog.State.Physical
if options.vstUseConcat: views |= CRL.Catalog.State.VstUseConcat
if options.saveDesign != cell.getName():
cell.setName(options.saveDesign)
views |= CRL.Catalog.State.Logical