diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 90ce9e95..97bd201a 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -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; diff --git a/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp b/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp index a978db12..1d8fb6c2 100644 --- a/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp +++ b/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp @@ -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; diff --git a/crlcore/src/ccore/alliance/vst/VhdlPortMap.cpp b/crlcore/src/ccore/alliance/vst/VhdlPortMap.cpp index b85324b4..2d8edb26 100644 --- a/crlcore/src/ccore/alliance/vst/VhdlPortMap.cpp +++ b/crlcore/src/ccore/alliance/vst/VhdlPortMap.cpp @@ -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 ) { diff --git a/crlcore/src/ccore/alliance/vst/VstDriver.cpp b/crlcore/src/ccore/alliance/vst/VstDriver.cpp index 8fb670ff..7789d0d8 100644 --- a/crlcore/src/ccore/alliance/vst/VstDriver.cpp +++ b/crlcore/src/ccore/alliance/vst/VstDriver.cpp @@ -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 ); diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index 12fc9b08..213f561e 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -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; diff --git a/crlcore/src/ccore/crlcore/VhdlEntity.h b/crlcore/src/ccore/crlcore/VhdlEntity.h index 015515ec..a5da68a6 100644 --- a/crlcore/src/ccore/crlcore/VhdlEntity.h +++ b/crlcore/src/ccore/crlcore/VhdlEntity.h @@ -66,6 +66,7 @@ namespace Vhdl { , AsInnerSignal = 0x0010 , VstUseConcat = 0x0020 }; + const unsigned int ModeMask = VstUseConcat; public: static std::vector& getAllEntities (); diff --git a/crlcore/src/pyCRL/PyRoutingGauge.cpp b/crlcore/src/pyCRL/PyRoutingGauge.cpp index bd5231f6..9e03d953 100644 --- a/crlcore/src/pyCRL/PyRoutingGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingGauge.cpp @@ -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 diff --git a/cumulus/src/plugins/chip/Configuration.py b/cumulus/src/plugins/chip/Configuration.py index 1d8beae4..9cfb341c 100644 --- a/cumulus/src/plugins/chip/Configuration.py +++ b/cumulus/src/plugins/chip/Configuration.py @@ -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 diff --git a/cumulus/src/plugins/chip/PadsCorona.py b/cumulus/src/plugins/chip/PadsCorona.py index 923f0dc7..5d6dc064 100644 --- a/cumulus/src/plugins/chip/PadsCorona.py +++ b/cumulus/src/plugins/chip/PadsCorona.py @@ -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 diff --git a/unicorn/src/cgt.py b/unicorn/src/cgt.py index e2b1f57b..b65cc049 100755 --- a/unicorn/src/cgt.py +++ b/unicorn/src/cgt.py @@ -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