Compare commits
5 Commits
devel
...
gitlab-tes
Author | SHA1 | Date |
---|---|---|
|
e457ab67d0 | |
|
bc8a2e02ce | |
|
68ade8ccde | |
|
10e87670db | |
|
caca7aabff |
|
@ -5,6 +5,8 @@
|
|||
Coriolis README
|
||||
===============
|
||||
|
||||
**Tag: Test 5 of LIP6 gitlab**
|
||||
|
||||
Coriolis is a free database, placement tool and routing tool for VLSI design.
|
||||
|
||||
|
||||
|
@ -25,7 +27,7 @@ Documentation
|
|||
|
||||
The complete documentation is available here, both in pdf & html:
|
||||
|
||||
./documentation/output/html
|
||||
./documentation/_build/html/index.html
|
||||
./documentation/UsersGuide/UsersGuide.pdf
|
||||
|
||||
The documentation of the latest *stable* version is also
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
find_package(VLSISAPD REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
find_package(ETESIAN REQUIRED)
|
||||
find_package(Doxygen)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
@ -26,7 +26,7 @@ IF(UNIX)
|
|||
FIND_LIBRARY(ANABATIC_LIBRARY_PATH
|
||||
NAMES anabatic
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATH_SUFFIXES lib${LIB_SUFFIX}
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
|
|
@ -20,13 +20,11 @@
|
|||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
|
@ -122,33 +120,6 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
class NonReducedItem {
|
||||
public:
|
||||
inline NonReducedItem ( AutoSegment* segment=NULL, uint32_t nonReduceds=0 );
|
||||
inline AutoSegment* segment () const;
|
||||
inline uint32_t nonReduceds () const;
|
||||
private:
|
||||
AutoSegment* _segment;
|
||||
uint32_t _nonReduceds;
|
||||
};
|
||||
|
||||
|
||||
inline NonReducedItem::NonReducedItem ( AutoSegment* segment, uint32_t nonReduceds )
|
||||
: _segment (segment)
|
||||
, _nonReduceds(nonReduceds)
|
||||
{ }
|
||||
|
||||
inline AutoSegment* NonReducedItem::segment () const { return _segment; }
|
||||
inline uint32_t NonReducedItem::nonReduceds () const { return _nonReduceds; }
|
||||
|
||||
bool operator< ( const NonReducedItem& lhs, const NonReducedItem& rhs )
|
||||
{
|
||||
int32_t deltaReduceds = (int32_t)lhs.nonReduceds() - (int32_t)rhs.nonReduceds();
|
||||
if (deltaReduceds > 0) return true; // Most connected first.
|
||||
if (deltaReduceds < 0) return false;
|
||||
return lhs.segment()->getId() < rhs.segment()->getId(); // Smallest Id first.
|
||||
}
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
|
@ -163,13 +134,11 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::NetRoutingExtension;
|
||||
using Hurricane::NetExternalComponents;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::UpdateSession;
|
||||
|
@ -311,27 +280,19 @@ namespace Anabatic {
|
|||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::NetData".
|
||||
|
||||
NetData::NetData ( Net* net, AnabaticEngine* anabatic )
|
||||
NetData::NetData ( Net* net )
|
||||
: _net (net)
|
||||
, _state (NetRoutingExtension::get(net))
|
||||
, _searchArea()
|
||||
, _rpCount (0)
|
||||
, _diodeCount(0)
|
||||
, _sparsity (0)
|
||||
, _flags ()
|
||||
{
|
||||
if (_state and _state->isMixedPreRoute()) return;
|
||||
|
||||
Cell* diodeCell = anabatic->getDiodeCell();
|
||||
for ( RoutingPad* rp : _net->getRoutingPads() ) {
|
||||
_searchArea.merge( rp->getBoundingBox() );
|
||||
++_rpCount;
|
||||
|
||||
if (diodeCell) {
|
||||
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
|
||||
if (plug and (plug->getInstance()->getMasterCell() == diodeCell))
|
||||
++_diodeCount;
|
||||
}
|
||||
}
|
||||
_update();
|
||||
}
|
||||
|
@ -373,15 +334,11 @@ namespace Anabatic {
|
|||
, _autoContactLut ()
|
||||
, _edgeCapacitiesLut()
|
||||
, _blockageNet (cell->getNet("blockagenet"))
|
||||
, _diodeCell (NULL)
|
||||
{
|
||||
_matrix.setCell( cell, _configuration->getSliceHeight() );
|
||||
Edge::unity = _configuration->getSliceHeight();
|
||||
|
||||
if (not _blockageNet) {
|
||||
_blockageNet = Net::create( cell, "blockagenet" );
|
||||
_blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
if (not _blockageNet) _blockageNet = Net::create( cell, "blockagenet" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -389,17 +346,9 @@ namespace Anabatic {
|
|||
{
|
||||
Super::_postCreate();
|
||||
|
||||
_diodeCell = DataBase::getDB()->getCell( getConfiguration()->getDiodeName() );;
|
||||
if (not _diodeCell) {
|
||||
cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell."
|
||||
, getConfiguration()->getDiodeName().c_str()
|
||||
) << endl;
|
||||
}
|
||||
|
||||
UpdateSession::open();
|
||||
GCell::create( this );
|
||||
UpdateSession::close();
|
||||
checkPlacement();
|
||||
}
|
||||
|
||||
|
||||
|
@ -446,7 +395,6 @@ namespace Anabatic {
|
|||
|
||||
void AnabaticEngine::_gutAnabatic ()
|
||||
{
|
||||
//DebugSession::open( 159, 160 );
|
||||
openSession();
|
||||
|
||||
_flags.reset( Flags::DestroyBaseContact|Flags::DestroyBaseSegment );
|
||||
|
@ -454,40 +402,19 @@ namespace Anabatic {
|
|||
if (_state == EngineDriving) {
|
||||
cdebug_log(145,1) << "Saving AutoContacts/AutoSegments." << endl;
|
||||
|
||||
vector<NonReducedItem> reduceds;
|
||||
size_t fixedSegments = 0;
|
||||
size_t sameLayerDoglegs = 0;
|
||||
size_t bloatedStraps = 0;
|
||||
for ( auto isegment : _autoSegmentLut ) {
|
||||
if (isegment.second->isFixed()) ++fixedSegments;
|
||||
if (isegment.second->canReduce( Flags::NullLength )) {
|
||||
//cerr << "push_back() " << (void*)isegment.second << ":" << isegment.second << endl;
|
||||
reduceds.push_back( NonReducedItem( isegment.second
|
||||
, isegment.second->getNonReduceds( Flags::NoFlags ) ));
|
||||
} else {
|
||||
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
|
||||
}
|
||||
//if (isegment.second->bloatStackedStrap()) ++bloatedStraps;
|
||||
}
|
||||
sort( reduceds.begin(), reduceds.end() );
|
||||
// cerr << "Reduced segment queue:" << endl;
|
||||
// for ( size_t i=0 ; i<reduceds.size() ; ++i ) {
|
||||
// cerr << "| " << setw(3) << i
|
||||
// << " " << reduceds[i].nonReduceds()
|
||||
// << " " << reduceds[i].segment() << endl;
|
||||
// }
|
||||
for ( auto& item : reduceds ) {
|
||||
item.segment()->reduce( Flags::NoFlags );
|
||||
if (item.segment()->reduceDoglegLayer()) ++sameLayerDoglegs;
|
||||
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
|
||||
}
|
||||
|
||||
cmess1 << " o Driving Hurricane data-base." << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoSegments" ,AutoSegment::getAllocateds()-fixedSegments) << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoContacts" ,AutoContact::getAllocateds()-fixedSegments*2) << endl;
|
||||
cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl;
|
||||
cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl;
|
||||
cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl;
|
||||
cmess1 << Dots::asSizet(" - Bloated straps (< minArea)",bloatedStraps ) << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoSegments",AutoSegment::getAllocateds()-fixedSegments) << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoContacts",AutoContact::getAllocateds()-fixedSegments*2) << endl;
|
||||
cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl;
|
||||
cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl;
|
||||
cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl;
|
||||
|
||||
//for ( Net* net : _cell->getNets() ) _saveNet( net );
|
||||
|
||||
|
@ -510,33 +437,14 @@ namespace Anabatic {
|
|||
_ovEdges.clear();
|
||||
}
|
||||
|
||||
exportExternalNets();
|
||||
Session::close();
|
||||
//DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::exportExternalNets ()
|
||||
{
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (not net->isExternal()) continue;
|
||||
if (net->isSupply()) continue;
|
||||
|
||||
for ( Segment* segment : net->getSegments() ) {
|
||||
NetExternalComponents::setExternal( segment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Configuration* AnabaticEngine::getConfiguration ()
|
||||
{ return _configuration; }
|
||||
|
||||
|
||||
const Configuration* AnabaticEngine::getConfiguration () const
|
||||
{ return _configuration; }
|
||||
|
||||
|
||||
Interval AnabaticEngine::getUSide ( Flags direction ) const
|
||||
{
|
||||
Interval side;
|
||||
|
@ -584,105 +492,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AnabaticEngine::checkPlacement () const
|
||||
{
|
||||
bool valid = true;
|
||||
Box cellAb = getCell()->getAbutmentBox();
|
||||
|
||||
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences() ) {
|
||||
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
||||
Cell* masterCell = instance->getMasterCell();
|
||||
string instanceName = occurrence.getCompactString();
|
||||
|
||||
instanceName.erase( 0, 1 );
|
||||
instanceName.erase( instanceName.size()-1 );
|
||||
|
||||
Box instanceAb = masterCell->getAbutmentBox();
|
||||
|
||||
Transformation instanceTransf = instance->getTransformation();
|
||||
occurrence.getPath().getTransformation().applyOn( instanceTransf );
|
||||
instanceTransf.applyOn( instanceAb );
|
||||
|
||||
if (not cellAb.contains(instanceAb)) {
|
||||
valid = false;
|
||||
cerr << Error( "AnabaticEngine::checkPlacement(): Instance %s is outside top cell abutment box, routing will be incomplete.\n"
|
||||
" (cell:%s vs instance:%s)"
|
||||
, instanceName.c_str()
|
||||
, getString(cellAb ).c_str()
|
||||
, getString(instanceAb).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
size_t errorCount = 0;
|
||||
ostringstream errors;
|
||||
errors << "AnabaticEngine::checkPlacement():\n";
|
||||
|
||||
for ( Net* net: getCell()->getNets() ) {
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
if (not pin) continue;
|
||||
|
||||
ostringstream pinError;
|
||||
|
||||
Point pinCenter = rp->getCenter();
|
||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
|
||||
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
|
||||
if (pin->getLayer() != getConfiguration()->getDVerticalLayer()) {
|
||||
pinError << " Should be in vertical routing layer, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< " vs gauge:" << getConfiguration()->getDVerticalLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin()
|
||||
- getConfiguration()->getDVerticalOffset())
|
||||
% getConfiguration()->getDVerticalPitch()) {
|
||||
pinError << " Misaligned, "
|
||||
<< "pin:" << DbU::getValueString(pinCenter.getX())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDVerticalPitch ())
|
||||
<< ", offset:" << DbU::getValueString(getConfiguration()->getDVerticalOffset())
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
|
||||
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
|
||||
if (pin->getLayer() != getConfiguration()->getDHorizontalLayer()) {
|
||||
pinError << " Should be in horizontal routing layer, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< " vs gauge:" << getConfiguration()->getDHorizontalLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin()
|
||||
- getConfiguration()->getDHorizontalOffset())
|
||||
% getConfiguration()->getDHorizontalPitch()) {
|
||||
pinError << " Misaligned, "
|
||||
<< "pin:" << DbU::getValueString(pinCenter.getY())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDHorizontalPitch ())
|
||||
<< ", offset:" << DbU::getValueString(getConfiguration()->getDHorizontalOffset())
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (not pinError.str().empty()) {
|
||||
errors << "On " << pin << "\n" << pinError.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorCount) throw Error( errors.str() );
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::openSession ()
|
||||
{ Session::_open(this); }
|
||||
|
||||
|
@ -709,10 +518,10 @@ namespace Anabatic {
|
|||
size_t oindex = _netOrdering.size();
|
||||
for ( Net* net : _cell->getNets() ) {
|
||||
if (_netDatas.find(net->getId()) != _netDatas.end()) continue;
|
||||
NetData* data = new NetData( net, this );
|
||||
NetData* data = new NetData( net );
|
||||
_netOrdering.push_back( data );
|
||||
|
||||
netHistogram.addSample( (float)(data->getRpCount() - data->getDiodeRpCount()), 0 );
|
||||
netHistogram.addSample( (float)data->getRpCount(), 0 );
|
||||
}
|
||||
|
||||
for ( ; oindex < _netOrdering.size() ; ++oindex ) {
|
||||
|
@ -790,7 +599,7 @@ namespace Anabatic {
|
|||
NetData* data = NULL;
|
||||
NetDatas::iterator idata = _netDatas.find( net->getId() );
|
||||
if (idata == _netDatas.end()) {
|
||||
data = new NetData( net, this );
|
||||
data = new NetData( net );
|
||||
_netDatas.insert( make_pair(net->getId(),data) );
|
||||
_netOrdering.push_back( data );
|
||||
// cerr << Bug( "AnabaticEngine::getNetData() - %s is missing in NetDatas table."
|
||||
|
@ -1074,17 +883,6 @@ namespace Anabatic {
|
|||
UpdateSession::open();
|
||||
for ( GCell* gcell : _gcells ) gcell->cleanupGlobal();
|
||||
UpdateSession::close();
|
||||
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (getConfiguration()->isGLayer(component->getLayer())) {
|
||||
cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n"
|
||||
" %s"
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1096,8 +894,6 @@ namespace Anabatic {
|
|||
if (_state > EngineGlobalLoaded)
|
||||
throw Error ("AnabaticEngine::loadGlobalRouting() : global routing already loaded.");
|
||||
|
||||
antennaProtect();
|
||||
|
||||
if (method == EngineLoadGrByNet ) { _loadGrByNet(); }
|
||||
else {
|
||||
throw Error( badMethod, "Anabatic::loadGlobalRouting()", method, getString(_cell).c_str() );
|
||||
|
@ -1241,10 +1037,7 @@ namespace Anabatic {
|
|||
//AutoSegment::setShortNetMode( true );
|
||||
++shortNets;
|
||||
}
|
||||
if (NetRoutingExtension::isManualDetailRoute(net))
|
||||
continue;
|
||||
if ( NetRoutingExtension::isManualGlobalRoute(net)
|
||||
or NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
DebugSession::open( net, 145, 150 );
|
||||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
||||
|
@ -1415,7 +1208,7 @@ namespace Anabatic {
|
|||
set<const Layer*> connectedLayers;
|
||||
|
||||
forEach ( Segment*, segment, net->getSegments() ) {
|
||||
if (segment->getAnchoredLength()) {
|
||||
if (segment->getLength()) {
|
||||
if (net->isExternal()) {
|
||||
NetExternalComponents::setExternal( *segment );
|
||||
}
|
||||
|
@ -1688,7 +1481,7 @@ namespace Anabatic {
|
|||
Edge* edge = neighbor->getWestEdge();
|
||||
if (not edge) break;
|
||||
|
||||
if (edge->getReservedCapacity() < (uint32_t)maxTermSat)
|
||||
if (edge->getReservedCapacity() < maxTermSat)
|
||||
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
|
||||
neighbor = neighbor->getWest();
|
||||
}
|
||||
|
@ -1697,7 +1490,7 @@ namespace Anabatic {
|
|||
Edge* edge = neighbor->getEastEdge();
|
||||
if (not edge) break;
|
||||
|
||||
if (edge->getReservedCapacity() < (uint32_t)maxTermSat)
|
||||
if (edge->getReservedCapacity() < maxTermSat)
|
||||
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
|
||||
neighbor = neighbor->getEast();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -178,7 +178,6 @@ namespace Anabatic {
|
|||
AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; }
|
||||
AutoVertical* AutoContact::getVertical1 () const { return NULL; }
|
||||
AutoVertical* AutoContact::getVertical2 () const { return NULL; }
|
||||
bool AutoContact::isOnPin () const { return false; }
|
||||
|
||||
|
||||
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
|
||||
|
@ -205,11 +204,10 @@ namespace Anabatic {
|
|||
size_t maxDepth = 0;
|
||||
|
||||
getDepthSpan( minDepth, maxDepth );
|
||||
setLayerAndWidth( maxDepth-minDepth, minDepth );
|
||||
// if (minDepth == maxDepth)
|
||||
// setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) );
|
||||
// else
|
||||
// setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) );
|
||||
if (minDepth == maxDepth)
|
||||
setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) );
|
||||
else
|
||||
setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -227,17 +225,14 @@ namespace Anabatic {
|
|||
size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
|
||||
DbU::Unit length;
|
||||
if (segment->isLocal()) {
|
||||
length = segment->getAnchoredLength();
|
||||
length = segment->getLength();
|
||||
lengths[depth] += length;
|
||||
|
||||
DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
|
||||
if ( not segment->isUnbound() and (abs(length) > sideLength) )
|
||||
cerr << Error( "AutoContact::getLength(): Suspicious length %s (> %s) of %s.\n"
|
||||
" (on: %s)"
|
||||
, DbU::getValueString(length).c_str()
|
||||
, DbU::getValueString(sideLength).c_str()
|
||||
, getString(segment).c_str()
|
||||
, getString(this).c_str()) << endl;
|
||||
cerr << Error("Suspicious length:%.2f of %s."
|
||||
,DbU::getValueString(length).c_str()
|
||||
,getString(segment).c_str()) << endl;
|
||||
} else {
|
||||
if (segment->isHorizontal()) {
|
||||
if (isSourceHook)
|
||||
|
@ -474,13 +469,12 @@ namespace Anabatic {
|
|||
|
||||
void AutoContact::setConstraintBox ( const Box& box )
|
||||
{
|
||||
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox()
|
||||
<< " from:" << box << endl;
|
||||
setCBXMin ( box.getXMin() );
|
||||
setCBXMax ( box.getXMax() );
|
||||
setCBYMin ( box.getYMin() );
|
||||
setCBYMax ( box.getYMax() );
|
||||
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox() << endl;
|
||||
cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox()
|
||||
<< " from:" << box << endl;
|
||||
cdebug_log(149,0) << "* " << _gcell << endl;
|
||||
}
|
||||
|
||||
|
@ -578,13 +572,8 @@ namespace Anabatic {
|
|||
|
||||
if (delta == 0) {
|
||||
setLayer( Session::getRoutingLayer(depth) );
|
||||
if (Session::getDirection(depth) & Flags::Horizontal) {
|
||||
setSizes( Session::getPWireWidth(depth)
|
||||
, Session::getWireWidth (depth) );
|
||||
} else {
|
||||
setSizes( Session::getWireWidth (depth)
|
||||
, Session::getPWireWidth(depth) );
|
||||
}
|
||||
setSizes( Session::getWireWidth (depth)
|
||||
, Session::getWireWidth (depth) );
|
||||
} else {
|
||||
setLayer( Session::getContactLayer(depth) );
|
||||
setSizes( Session::getViaWidth (depth)
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
|
@ -48,7 +47,6 @@ namespace Anabatic {
|
|||
using Hurricane::Transformation;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Occurrence;
|
||||
using Hurricane::Pin;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -131,13 +129,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoContactTerminal::isOnPin () const
|
||||
{
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( getAnchor() );
|
||||
return (dynamic_cast<Pin*>(rp->getOccurrence().getEntity()) != NULL);
|
||||
}
|
||||
|
||||
|
||||
AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const
|
||||
{ return NULL; }
|
||||
|
||||
|
|
|
@ -88,17 +88,8 @@ namespace Anabatic {
|
|||
|
||||
AutoSegment* AutoContactTurn::getPerpandicular ( const AutoSegment* reference ) const
|
||||
{
|
||||
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
|
||||
<< " to:" << reference << endl;
|
||||
cdebug_log(149,0) << "| _horizontal1:" << _horizontal1 << endl;
|
||||
cdebug_log(149,0) << "| _vertical1 :" << _vertical1 << endl;
|
||||
|
||||
if (reference == _horizontal1) return _vertical1;
|
||||
if (reference == _vertical1 ) return _horizontal1;
|
||||
|
||||
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
|
||||
<< " to:" << reference << " failed." << endl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -126,9 +117,6 @@ namespace Anabatic {
|
|||
|
||||
void AutoContactTurn::cacheDetach ( AutoSegment* segment )
|
||||
{
|
||||
cdebug_log(149,0) << _getTypeName() << "::cacheDetach() " << this
|
||||
<< " from:" << segment << endl;
|
||||
|
||||
if (segment == _horizontal1) _horizontal1 = NULL;
|
||||
else if (segment == _vertical1) _vertical1 = NULL;
|
||||
else return;
|
||||
|
@ -139,9 +127,6 @@ namespace Anabatic {
|
|||
|
||||
void AutoContactTurn::cacheAttach ( AutoSegment* segment )
|
||||
{
|
||||
cdebug_log(149,0) << _getTypeName() << "::cacheAttach() " << this
|
||||
<< " to:" << segment << endl;
|
||||
|
||||
if (segment->getDirection() == Flags::Horizontal) {
|
||||
if (_horizontal1) {
|
||||
cerr << Bug( "%s::cacheAttach() On %s,\n"
|
||||
|
|
|
@ -47,8 +47,8 @@ namespace Anabatic {
|
|||
Segment* AutoHorizontal::base () { return _horizontal; }
|
||||
Segment* AutoHorizontal::base () const { return _horizontal; }
|
||||
Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; }
|
||||
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSource()->getX(); }
|
||||
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTarget()->getX(); }
|
||||
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSourceX(); }
|
||||
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTargetX(); }
|
||||
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
|
||||
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
|
||||
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
|
||||
|
@ -93,14 +93,6 @@ namespace Anabatic {
|
|||
mergeNativeMax( gcell->getConstraintYMax() );
|
||||
}
|
||||
}
|
||||
|
||||
// if (getId() == 1518590) {
|
||||
// cerr << "AutoHorizontal::_postCreate(): " << this << endl;
|
||||
// cerr << "| Source contact:" << source << endl;
|
||||
// cerr << "| Source GCell: " << getGCell() << endl;
|
||||
// cerr << "| Target contact:" << target << endl;
|
||||
// cerr << "| Target GCell: " << target->getGCell() << endl;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -232,15 +224,13 @@ namespace Anabatic {
|
|||
gcell = gcell->getEast( yprobe );
|
||||
if (not gcell) {
|
||||
success = false;
|
||||
if (not isCreated()) {
|
||||
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
|
||||
" begin:%s\n"
|
||||
" end: %s"
|
||||
, getString(this).c_str()
|
||||
, getString(getAutoSource()->getGCell()).c_str()
|
||||
, getString(getAutoTarget()->getGCell()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
|
||||
" begin:%s\n"
|
||||
" end: %s"
|
||||
, getString(this).c_str()
|
||||
, getString(getAutoSource()->getGCell()).c_str()
|
||||
, getString(getAutoTarget()->getGCell()).c_str()
|
||||
) << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -255,9 +245,8 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_tabw(149,1);
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
if (source->isOnPin() or target->isOnPin()) { cdebug_tabw(149,-1); return false; }
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
||||
Interval sourceSide = source->getGCell()->getSide( Flags::Vertical );
|
||||
Interval targetSide = target->getGCell()->getSide( Flags::Vertical );
|
||||
|
@ -325,9 +314,6 @@ namespace Anabatic {
|
|||
isNonPrefSource = true;
|
||||
slackenSource = true;
|
||||
}
|
||||
|
||||
cdebug_log(149,0) << "target:" << target << endl;
|
||||
cdebug_log(149,0) << "target->getPerpandicular(this):" << target->getPerpandicular(this) << endl;
|
||||
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) {
|
||||
isNonPrefTarget = true;
|
||||
slackenTarget = true;
|
||||
|
@ -335,11 +321,11 @@ namespace Anabatic {
|
|||
|
||||
cdebug_tabw(149,1);
|
||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getAnchoredLength() < 5*getPitch()) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
|
||||
|
||||
if (height >= 4*getPitch()) {
|
||||
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < 5*getPitch())) {
|
||||
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch())) {
|
||||
cdebug_log(149,0) << "Too short terminal segment to slacken." << endl;
|
||||
cdebug_tabw(149,-1);
|
||||
return false;
|
||||
|
@ -413,15 +399,7 @@ namespace Anabatic {
|
|||
|
||||
const vector<AutoSegment*>& doglegs = Session::getDoglegs();
|
||||
if (targetSlackened and (doglegs.size() >= 2)) {
|
||||
GCell* targetGCell = target->getGCell();
|
||||
Box constraintBox = target->getConstraintBox();
|
||||
cdebug_log(149,0) << "slacken from Target @" << DbU::getValueString(targetPosition) << endl;
|
||||
|
||||
if (targetPosition >= targetGCell->getXMax()) {
|
||||
cdebug_log(149,0) << "On the rigthmost track, adjust of one P-pitch to the left." << endl;
|
||||
targetPosition -= getPPitch();
|
||||
constraintBox.inflate( getPPitch(), 0, 0, 0 );
|
||||
}
|
||||
cdebug_log(149,0) << "AutoHorizontal::_slacken(): Target @" << DbU::getValueString(targetPosition) << endl;
|
||||
doglegs[doglegs.size()-2]->setAxis( targetPosition );
|
||||
success = true;
|
||||
|
||||
|
@ -429,7 +407,7 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "Fixing on target terminal contact: "
|
||||
<< doglegs[doglegs.size()-2]->getAutoTarget() << endl;
|
||||
//doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntFixed );
|
||||
doglegs[doglegs.size()-2]->getAutoTarget()->setConstraintBox( constraintBox );
|
||||
doglegs[doglegs.size()-2]->getAutoTarget()->setConstraintBox( target->getConstraintBox() );
|
||||
doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntUserNativeConstraints );
|
||||
}
|
||||
}
|
||||
|
@ -486,18 +464,9 @@ namespace Anabatic {
|
|||
|
||||
void AutoHorizontal::updateOrient ()
|
||||
{
|
||||
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
|
||||
if (_horizontal->getTargetX() < _horizontal->getSourceX()) {
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
if (isAtMinArea()) {
|
||||
DbU::Unit sourceX = _horizontal->getSourceX();
|
||||
DbU::Unit targetX = _horizontal->getTargetX();
|
||||
_horizontal->invert();
|
||||
setDuSource( sourceX - getSourceU() );
|
||||
setDuTarget( targetX - getTargetU() );
|
||||
} else {
|
||||
_horizontal->invert();
|
||||
}
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
|
||||
_horizontal->invert();
|
||||
|
||||
uint64_t spinFlags = _flags & SegDepthSpin;
|
||||
unsetFlags( SegDepthSpin );
|
||||
|
@ -521,8 +490,8 @@ namespace Anabatic {
|
|||
|
||||
void AutoHorizontal::updatePositions ()
|
||||
{
|
||||
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
|
||||
_sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,8 +511,8 @@ namespace Anabatic {
|
|||
bool AutoHorizontal::checkPositions () const
|
||||
{
|
||||
bool coherency = true;
|
||||
DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target);
|
||||
DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
||||
|
||||
if ( _sourcePosition != sourcePosition ) {
|
||||
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Bug.h"
|
||||
|
@ -348,7 +347,7 @@ namespace Anabatic {
|
|||
if ( deltaUnit < 0 ) return true; // Smallest source first.
|
||||
if ( deltaUnit > 0 ) return false;
|
||||
|
||||
deltaUnit = lhs->getAnchoredLength() - rhs->getAnchoredLength();
|
||||
deltaUnit = lhs->getLength() - rhs->getLength();
|
||||
if ( deltaUnit > 0 ) return true; // Longest first.
|
||||
if ( deltaUnit < 0 ) return false;
|
||||
|
||||
|
@ -409,32 +408,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::AutoSegment::CompareByRevalidate".
|
||||
|
||||
|
||||
bool AutoSegment::CompareByRevalidate::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const
|
||||
{
|
||||
if (lhs->isNonPref() xor rhs->isNonPref() ) return lhs->isNonPref();
|
||||
|
||||
DbU::Unit deltaLength = lhs->getAnchoredLength() - rhs->getAnchoredLength();
|
||||
if (deltaLength > 0) return true; // Longest length first.
|
||||
if (deltaLength < 0) return false;
|
||||
|
||||
return lhs->getId() < rhs->getId(); // Smallest Id first.
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::CompareByReduceds::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const
|
||||
{
|
||||
uint32_t deltaReduceds = lhs->getReduceds() - rhs->getReduceds();
|
||||
if (deltaReduceds < 0) return true; // Smallest source first.
|
||||
if (deltaReduceds > 0) return false;
|
||||
|
||||
return lhs->getId() < rhs->getId(); // Smallest Id first.
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::AutoSegment".
|
||||
|
||||
|
@ -444,7 +417,7 @@ namespace Anabatic {
|
|||
bool AutoSegment::_analogMode = false;
|
||||
bool AutoSegment::_shortNetMode = false;
|
||||
bool AutoSegment::_initialized = false;
|
||||
vector< array<DbU::Unit*,4> > AutoSegment::_extensionCaps;
|
||||
vector< array<DbU::Unit*,3> > AutoSegment::_extensionCaps;
|
||||
|
||||
|
||||
void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; }
|
||||
|
@ -457,19 +430,17 @@ namespace Anabatic {
|
|||
//cerr << "AutoSegment::_initialize()" << endl;
|
||||
|
||||
_initialized = true;
|
||||
DbU::Unit twoGrid = DbU::fromGrid( 2 );
|
||||
for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) {
|
||||
DbU::Unit* viaToTopCap = new DbU::Unit ( 0 );
|
||||
DbU::Unit* viaToBottomCap = new DbU::Unit ( 0 );
|
||||
DbU::Unit* viaToSameCap = new DbU::Unit ( 0 );
|
||||
DbU::Unit* minimalLength = new DbU::Unit ( 0 );
|
||||
bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical());
|
||||
uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ;
|
||||
|
||||
//cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
|
||||
// << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
|
||||
|
||||
*viaToSameCap = Session::getPWireWidth(depth)/2;
|
||||
*viaToSameCap = Session::getWireWidth(depth)/2;
|
||||
|
||||
// Bottom metal of the VIA going *up*.
|
||||
const Layer* viaLayer = dynamic_cast<const ViaLayer*>( Session::getContactLayer(depth) );
|
||||
|
@ -483,15 +454,6 @@ namespace Anabatic {
|
|||
*viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags );
|
||||
}
|
||||
|
||||
const Layer* routingLayer = Session::getRoutingLayer( depth );
|
||||
double minimalArea = routingLayer->getMinimalArea();
|
||||
if (minimalArea != 0.0) {
|
||||
*minimalLength = DbU::fromMicrons( minimalArea / DbU::toMicrons( Session::getWireWidth(depth) ) );
|
||||
DbU::Unit modulo = *minimalLength % twoGrid;
|
||||
if (modulo)
|
||||
*minimalLength += twoGrid - modulo;
|
||||
}
|
||||
|
||||
//cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
|
||||
//cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl;
|
||||
//if (depth > 0)
|
||||
|
@ -499,10 +461,7 @@ namespace Anabatic {
|
|||
//cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl;
|
||||
//cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl;
|
||||
|
||||
_extensionCaps.push_back( std::array<DbU::Unit*,4>( {{ viaToTopCap
|
||||
, viaToBottomCap
|
||||
, viaToSameCap
|
||||
, minimalLength }} ) );
|
||||
_extensionCaps.push_back( std::array<DbU::Unit*,3>( {{ viaToTopCap, viaToBottomCap, viaToSameCap }} ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,11 +534,6 @@ namespace Anabatic {
|
|||
|
||||
_observers.notify( Destroy );
|
||||
|
||||
AutoContact* contact = getAutoSource();
|
||||
if (contact) contact->cacheDetach( this );
|
||||
contact = getAutoTarget();
|
||||
if (contact) contact->cacheDetach( this );
|
||||
|
||||
Session::unlink( this );
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
@ -714,10 +668,6 @@ namespace Anabatic {
|
|||
incReduceds();
|
||||
}
|
||||
|
||||
Interval oldSpan = Interval( _sourcePosition, _targetPosition );
|
||||
if (not expandToMinLength(oldSpan)) {
|
||||
unexpandToMinLength();
|
||||
}
|
||||
updatePositions();
|
||||
|
||||
unsigned int observerFlags = Revalidate;
|
||||
|
@ -770,53 +720,20 @@ namespace Anabatic {
|
|||
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||
cdebug_log(145,0) << "getExtensionCap(): flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< " " << (getFlags() & SegSourceBottom)
|
||||
<< endl;
|
||||
if (not (flags & Flags::NoSegExt)) {
|
||||
cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
|
||||
if (-getDuSource() > cap) {
|
||||
cap = -getDuSource();
|
||||
cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & Flags::Target) {
|
||||
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< endl;
|
||||
if (not (flags & Flags::NoSegExt)) {
|
||||
cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
|
||||
if (getDuTarget() > cap) {
|
||||
cap = getDuTarget();
|
||||
cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if ( not isCreated()
|
||||
// and not (flags & Flags::NoMinLength)
|
||||
// and (flags & Flags::Target)
|
||||
// and (getMinimalLength(depth) != 0.0)
|
||||
// and isMiddleStack() ) {
|
||||
// DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||
// + getAnchoredLength();
|
||||
// if (realLength + cap < getMinimalLength(depth)) {
|
||||
// cap = getMinimalLength(depth) - realLength;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2;
|
||||
if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2;
|
||||
return cap;
|
||||
if (cap < getWidth()/2) cap = getWidth()/2;
|
||||
return cap + getLayer()->getMinimalSpacing()/2;;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1388,7 +1305,7 @@ namespace Anabatic {
|
|||
if (terminalMin != terminalMax)
|
||||
attractors.addAttractor( terminalMax );
|
||||
}
|
||||
} else if (autoSegment->isLongLocal() or (autoSegment->getAnchoredLength() > getPPitch()*20)) {
|
||||
} else if (autoSegment->isLongLocal() or (autoSegment->getLength() > getPPitch()*20)) {
|
||||
cdebug_log(145,0) << "Used as long global attractor." << endl;
|
||||
|
||||
DbU::Unit perpandMin = autoSegment->getSourceU();
|
||||
|
@ -1612,135 +1529,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::isMiddleStack () const
|
||||
{
|
||||
cdebug_log(149,0) << "AutoSegment::isMiddleStack() - " << this << endl;
|
||||
if (not isCanonical()) return false;
|
||||
if (isNonPref()) return false;
|
||||
if (isGlobal()) {
|
||||
if (getLength() > getPPitch()) return false;
|
||||
cdebug_log(149,0) << "| Considering this global anyway because it is too short. " << endl;
|
||||
}
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
if (not source or not target) {
|
||||
cdebug_log(149,0) << "| false, missing source or target (in creation?). " << endl;
|
||||
return false;
|
||||
}
|
||||
if (isSpinTopOrBottom()) {
|
||||
cdebug_log(149,0) << "| false, neither spin top nor bottom. " << endl;
|
||||
return false;
|
||||
}
|
||||
if (not (source->isTerminal() xor target->isTerminal())) {
|
||||
if (source->isTerminal() and target->isTerminal()) {
|
||||
cdebug_log(149,0) << "| false, source & target are terminals. " << endl;
|
||||
return false;
|
||||
}
|
||||
if (source->isTurn()) {
|
||||
AutoSegment* perpandicular = source->getPerpandicular( this );
|
||||
if (perpandicular->isNonPref() and (perpandicular->getAnchoredLength() != 0)) {
|
||||
cdebug_log(149,0) << "| false, perpandicular is non-pref and non-zero. " << this << endl;
|
||||
return false;
|
||||
}
|
||||
} else if (target->isTurn()) {
|
||||
AutoSegment* perpandicular = target->getPerpandicular( this );
|
||||
if (perpandicular->isNonPref() and (perpandicular->getAnchoredLength() != 0)) {
|
||||
cdebug_log(149,0) << "| false, perpandicular is non-pref and non-zero. " << this << endl;
|
||||
return false;
|
||||
}
|
||||
} else if ((source->isHTee() or target->isHTee()) and isHorizontal()) {
|
||||
cdebug_log(149,0) << "| false, S/T HTee+Terminal and horizontal. " << this << endl;
|
||||
return false;
|
||||
} else if ((source->isVTee() or target->isVTee()) and isVertical()) {
|
||||
cdebug_log(149,0) << "| false, S/T VTee+Terminal and vertical. " << this << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DbU::Unit sourceAxis = 0;
|
||||
DbU::Unit targetAxis = 0;
|
||||
getEndAxes( sourceAxis, targetAxis );
|
||||
if ((targetAxis - sourceAxis) >= getPPitch()) {
|
||||
cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl;
|
||||
return false;
|
||||
}
|
||||
cdebug_log(149,0) << " Middle stack or terminal bound." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::isUnderMinLength () const
|
||||
{
|
||||
return false;
|
||||
// cdebug_log(149,0) << "AutoSegment::isUnderMinLength() - " << this << endl;
|
||||
// if (not isMiddleStack()) return false;
|
||||
// DbU::Unit spanLength = getSpanLength();
|
||||
// DbU::Unit minimalLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||
// cdebug_log(149,0) << " span=" << DbU::getValueString(spanLength)
|
||||
// << " < min=" << DbU::getValueString(minimalLength)<< endl;
|
||||
// return spanLength < minimalLength;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::expandToMinLength ( Interval span )
|
||||
{
|
||||
if (not isMiddleStack()) return false;
|
||||
cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl;
|
||||
cdebug_log(149,0) << "In span=" << span << endl;
|
||||
cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
|
||||
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
|
||||
<< "]" << endl;
|
||||
|
||||
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap;
|
||||
DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||
if (techMinLength <= segMinLength) {
|
||||
cdebug_log(149,0) << "Above minimal length (" << DbU::getValueString(segMinLength)
|
||||
<< " >= " << DbU::getValueString(techMinLength) << ")" << endl;
|
||||
cdebug_tabw(149,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
DbU::Unit oneGrid = DbU::fromGrid( 1 );
|
||||
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
|
||||
DbU::Unit sourceExpand = - (techMinLength - segMinLength) / 2 - sourceCap;
|
||||
if (targetExpand % oneGrid)
|
||||
targetExpand += oneGrid - targetExpand % oneGrid;
|
||||
if (sourceExpand % oneGrid)
|
||||
sourceExpand -= oneGrid + sourceExpand % oneGrid;
|
||||
if (not span.isEmpty()) {
|
||||
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand);
|
||||
if (shiftLeft < 0) {
|
||||
targetExpand += shiftLeft;
|
||||
sourceExpand += shiftLeft;
|
||||
}
|
||||
}
|
||||
setDuSource( sourceExpand );
|
||||
setDuTarget( targetExpand );
|
||||
cdebug_log(149,0) << "sourceExpand=" << DbU::getValueString(sourceExpand)
|
||||
<< " targetExpand=" << DbU::getValueString(targetExpand) << endl;
|
||||
cdebug_log(149,0) << "After: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
|
||||
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
|
||||
<< "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl;
|
||||
setFlags( SegAtMinArea );
|
||||
cdebug_tabw(149,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::unexpandToMinLength ()
|
||||
{
|
||||
if (not isAtMinArea()) return false;
|
||||
cdebug_log(149,0) << "AutoSegment::unexpandToMinLength() " << this << endl;
|
||||
setDuSource( 0 );
|
||||
setDuTarget( 0 );
|
||||
unsetFlags( SegAtMinArea );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::isReduceCandidate () const
|
||||
{
|
||||
if (isGlobal()) return false;
|
||||
|
@ -1756,18 +1544,14 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::canReduce ( Flags flags ) const
|
||||
bool AutoSegment::canReduce () const
|
||||
{
|
||||
cdebug_log(159,0) << "AutoSegment::canReduce():" << this << endl;
|
||||
cdebug_log(159,0) << " _reduceds:" << _reduceds << endl;
|
||||
|
||||
DbU::Unit length = getAnchoredLength();
|
||||
if (isGlobal() and (length > getPPitch())) return false;
|
||||
|
||||
if (isDrag() or isFixed()) return false;
|
||||
if (isGlobal() or isDrag() or isFixed()) return false;
|
||||
if (not isSpinTopOrBottom()) return false;
|
||||
if ((getDepth() == 1) and isSpinBottom()) return false;
|
||||
if ((flags & Flags::WithPerpands) and _reduceds) return false;
|
||||
if (_reduceds) return false;
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
@ -1781,9 +1565,6 @@ namespace Anabatic {
|
|||
// if ( source->isHTee() or source->isVTee()
|
||||
// or target->isHTee() or target->isVTee() ) return false;
|
||||
|
||||
cdebug_log(159,0) << " length:" << DbU::getValueString(length) << endl;
|
||||
if (flags & Flags::NullLength) return (length == 0);
|
||||
|
||||
unsigned int perpandicularDepth = getDepth();
|
||||
if (isSpinBottom()) {
|
||||
if (perpandicularDepth > 0) --perpandicularDepth;
|
||||
|
@ -1792,18 +1573,17 @@ namespace Anabatic {
|
|||
if (perpandicularDepth >= Session::getDepth()) return false;
|
||||
} else
|
||||
return false;
|
||||
|
||||
if (getAnchoredLength() >= Session::getPitch(perpandicularDepth) * 2) return false;
|
||||
|
||||
cdebug_log(159,0) << " length:" << DbU::getValueString(getLength()) << endl;
|
||||
if (getLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::reduce ( Flags flags )
|
||||
bool AutoSegment::reduce ()
|
||||
{
|
||||
if (isReduced()) return false;
|
||||
if (not canReduce(flags)) return false;
|
||||
cdebug_log(159,0) << "AutoSegment::reduce():" << this << endl;
|
||||
if (not canReduce()) return false;
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
@ -1818,29 +1598,10 @@ namespace Anabatic {
|
|||
perpandicular->incReduceds();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t AutoSegment::getNonReduceds ( Flags flags ) const
|
||||
{
|
||||
if (not canReduce(flags)) return false;
|
||||
cdebug_log(159,0) << "AutoSegment::getNonReduceds():" << this << endl;
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
uint32_t nonReduceds = 0;
|
||||
|
||||
for ( AutoSegment* perpandicular : source->getAutoSegments() ) {
|
||||
if (perpandicular == this) continue;
|
||||
if (perpandicular->getAnchoredLength()) ++nonReduceds;
|
||||
}
|
||||
for ( AutoSegment* perpandicular : target->getAutoSegments() ) {
|
||||
if (perpandicular == this) continue;
|
||||
if (perpandicular->getAnchoredLength()) ++nonReduceds;
|
||||
}
|
||||
// if (not source->isTerminal()) source->getPerpandicular( this )->incReduceds();
|
||||
// if (not target->isTerminal()) target->getPerpandicular( this )->incReduceds();
|
||||
|
||||
return nonReduceds;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1853,27 +1614,26 @@ namespace Anabatic {
|
|||
else if (isSpinTop ()) ++perpandicularDepth;
|
||||
else return true;
|
||||
|
||||
return (getAnchoredLength() >= (Session::getPitch(perpandicularDepth) * 2));
|
||||
return (getLength() >= (Session::getPitch(perpandicularDepth) * 2));
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::raise ()
|
||||
{
|
||||
if (not (_flags & SegIsReduced)) return false;
|
||||
cdebug_log(159,0) << "AutoSegment::raise():" << this << endl;
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
||||
_flags &= ~SegIsReduced;
|
||||
//if (not source->isTerminal()) source->getPerpandicular( this )->decReduceds();
|
||||
//if (not target->isTerminal()) target->getPerpandicular( this )->decReduceds();
|
||||
for ( AutoSegment* perpandicular : source->getAutoSegments() ) {
|
||||
if (perpandicular == this) continue;
|
||||
cdebug_log(159,0) << "dec PP:" << perpandicular << endl;
|
||||
perpandicular->decReduceds();
|
||||
}
|
||||
for ( AutoSegment* perpandicular : target->getAutoSegments() ) {
|
||||
if (perpandicular == this) continue;
|
||||
cdebug_log(159,0) << "dec PP:" << perpandicular << endl;
|
||||
perpandicular->decReduceds();
|
||||
}
|
||||
|
||||
|
@ -1964,8 +1724,8 @@ namespace Anabatic {
|
|||
|
||||
if (_canSlacken()) return true;
|
||||
if ((flags & Flags::Propagate) and not isNotAligned()) {
|
||||
for ( AutoSegment* segment : const_cast<AutoSegment*>(this)->getAligneds() ) {
|
||||
if (segment->_canSlacken()) return true;
|
||||
forEach ( AutoSegment*, isegment, const_cast<AutoSegment*>(this)->getAligneds() ) {
|
||||
if (isegment->_canSlacken()) return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2117,12 +1877,6 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(159,0) << "AutoSegment::canMoveUp() " << flags
|
||||
<< " (reserve:" << reserve << ") " << this << endl;
|
||||
if (Session::getRoutingGauge()->getName() == "FlexLib")
|
||||
reserve += 2.0;
|
||||
|
||||
// ls180 hard-coded hack.
|
||||
//if (getId() == 10023986) return false;
|
||||
if (getId() == 6378409) return false;
|
||||
|
||||
bool nLowDensity = true;
|
||||
bool nLowUpDensity = true;
|
||||
|
@ -2241,14 +1995,13 @@ namespace Anabatic {
|
|||
|
||||
bool AutoSegment::reduceDoglegLayer ()
|
||||
{
|
||||
if (not isReduced()) return false;
|
||||
if (not isReduced()) return true;
|
||||
|
||||
DebugSession::open( getNet(), 149, 160 );
|
||||
cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl;
|
||||
|
||||
bool success = false;
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
||||
unsigned int minSourceDepth = Session::getAllowedDepth();
|
||||
unsigned int maxSourceDepth = 0;
|
||||
|
@ -2259,11 +2012,9 @@ namespace Anabatic {
|
|||
unsigned int anchorDepth = Session::getLayerDepth( source->base()->getAnchor()->getLayer() );
|
||||
minSourceDepth = std::min( minSourceDepth, anchorDepth );
|
||||
maxSourceDepth = std::max( maxSourceDepth, anchorDepth );
|
||||
cdebug_log(151,0) << " source:" << source << endl;
|
||||
} else {
|
||||
for ( AutoSegment* perpandicular : source->getAutoSegments() ) {
|
||||
if (perpandicular == this) continue;
|
||||
cdebug_log(151,0) << " connected:" << perpandicular << endl;
|
||||
minSourceDepth = std::min( minSourceDepth, perpandicular->getDepth() );
|
||||
maxSourceDepth = std::max( maxSourceDepth, perpandicular->getDepth() );
|
||||
}
|
||||
|
@ -2272,11 +2023,9 @@ namespace Anabatic {
|
|||
unsigned int anchorDepth = Session::getLayerDepth( target->base()->getAnchor()->getLayer() );
|
||||
minTargetDepth = std::min( minTargetDepth, anchorDepth );
|
||||
maxTargetDepth = std::max( maxTargetDepth, anchorDepth );
|
||||
cdebug_log(151,0) << " target:" << target << endl;
|
||||
} else {
|
||||
for ( AutoSegment* perpandicular : target->getAutoSegments() ) {
|
||||
if (perpandicular == this) continue;
|
||||
cdebug_log(151,0) << " connected:" << perpandicular << endl;
|
||||
minTargetDepth = std::min( minTargetDepth, perpandicular->getDepth() );
|
||||
maxTargetDepth = std::max( maxTargetDepth, perpandicular->getDepth() );
|
||||
}
|
||||
|
@ -2289,26 +2038,20 @@ namespace Anabatic {
|
|||
and (minTargetDepth == maxTargetDepth)
|
||||
and (minSourceDepth == minTargetDepth) ) {
|
||||
const Layer* layer = Session::getRoutingLayer(minSourceDepth);
|
||||
DbU::Unit vside = Session::getWireWidth (minSourceDepth);
|
||||
DbU::Unit hside = Session::getPWireWidth (minSourceDepth);
|
||||
if (Session::getDirection(minSourceDepth) & Flags::Vertical)
|
||||
std::swap( hside, vside );
|
||||
DbU::Unit side = Session::getWireWidth (minSourceDepth);
|
||||
|
||||
cdebug_log(159,0) << "Reducing to " << minSourceDepth << " " << layer << endl;
|
||||
|
||||
source->setLayer( layer );
|
||||
target->setLayer( layer );
|
||||
setLayer( layer );
|
||||
setWidth( hside );
|
||||
source->setSizes( hside, vside );
|
||||
target->setSizes( hside, vside );
|
||||
|
||||
success = true;
|
||||
source->setSizes( side, side );
|
||||
target->setSizes( side, side );
|
||||
}
|
||||
|
||||
cdebug_tabw(159,-1);
|
||||
DebugSession::close();
|
||||
return success;
|
||||
return true;
|
||||
|
||||
|
||||
// if (not source->isTurn() or not target->isTurn()) return true;
|
||||
|
@ -2337,55 +2080,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::bloatStackedStrap ()
|
||||
{
|
||||
DebugSession::open( getNet(), 145, 150 );
|
||||
cdebug_log(149,1) << "AutoSegment::bloatStackedStrap() " << this << endl;
|
||||
double minArea = getLayer()->getMinimalArea();
|
||||
if (minArea == 0.0) {
|
||||
cdebug_log(149,-1) << "False, NO minimal area." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
|
||||
DbU::Unit minLength
|
||||
= DbU::fromPhysical( minArea / DbU::toPhysical( getWidth(), DbU::UnitPower::Micro )
|
||||
, DbU::UnitPower::Micro );
|
||||
cdebug_log(149,0) << "Min length: " << DbU::getValueString(minLength) << " ." << endl;
|
||||
|
||||
if ((getSpanLength() >= minLength) or isReduced()) {
|
||||
cdebug_log(149,-1) << "False, has length or is reduced." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
if (isDrag()) {
|
||||
for ( AutoSegment* perpandicular : getPerpandiculars() ) {
|
||||
if (perpandicular->getSpanLength() > minLength) {
|
||||
cdebug_log(149,-1) << "False (drag), has length or PP has length." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ((_flags & (SegSourceBottom|SegTargetTop)) != (SegSourceBottom|SegTargetTop))
|
||||
and ((_flags & (SegTargetBottom|SegSourceTop)) != (SegTargetBottom|SegSourceTop)) ) {
|
||||
cdebug_log(149,-1) << "False, not part of a stacked VIA." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DbU::Unit side = DbU::fromPhysical( std::sqrt(minArea) , DbU::UnitPower::Micro );
|
||||
setWidth( side );
|
||||
setDuSource( -side/2 );
|
||||
setDuTarget( side/2 );
|
||||
|
||||
cdebug_log(149,-1) << "True, add area." << endl;
|
||||
DebugSession::close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if THIS_IS_DISABLED
|
||||
bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags )
|
||||
{
|
||||
|
@ -2870,10 +2564,9 @@ namespace Anabatic {
|
|||
segment->_postCreate();
|
||||
} else if (vertical) {
|
||||
if (vertical->getLayer() != verticalLayer) {
|
||||
if (Session::getAnabatic()->getConfiguration()->isGMetal(vertical->getLayer()) ) {
|
||||
vertical->setLayer( verticalLayer );
|
||||
vertical->setWidth( verticalWidth );
|
||||
}
|
||||
if (Session::getAnabatic()->getConfiguration()->isGMetal(vertical->getLayer()) )
|
||||
vertical->setLayer( verticalLayer );
|
||||
vertical->setWidth( verticalWidth );
|
||||
} else {
|
||||
if (vertical->getWidth() != verticalWidth) {
|
||||
cerr << Warning("Segment %s has non-default width %s."
|
||||
|
@ -2914,16 +2607,14 @@ namespace Anabatic {
|
|||
|
||||
if (dir & Flags::UseNonPref) {
|
||||
if (dir & Flags::Vertical) {
|
||||
cdebug_log(149,0) << "Make vertical in non-preferred direction." << endl;
|
||||
vLayer = hLayer;
|
||||
vWidth = Session::getDPHorizontalWidth();
|
||||
cdebug_log(149,0) << "Make vertical in non-preferred direction (ppW:"
|
||||
<< DbU::getValueString(vWidth).c_str() << ")." << endl;
|
||||
vWidth = hWidth;
|
||||
}
|
||||
if (dir & Flags::Horizontal) {
|
||||
cdebug_log(149,0) << "Make horizontal in non-preferred direction." << endl;
|
||||
hLayer = vLayer;
|
||||
hWidth = Session::getDPVerticalWidth();
|
||||
cdebug_log(149,0) << "Make horizontal in non-preferred direction (ppW:"
|
||||
<< DbU::getValueString(hWidth).c_str() << ")." << endl;
|
||||
hWidth = vWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2931,14 +2622,12 @@ namespace Anabatic {
|
|||
DbU::Unit horizontalWidth = hWidth;
|
||||
const Layer* verticalLayer = vLayer;
|
||||
DbU::Unit verticalWidth = vWidth;
|
||||
cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl;
|
||||
|
||||
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
|
||||
if (wPitch > 1) {
|
||||
horizontalWidth = (wPitch-1) * Session::getDHorizontalPitch() + hWidth;
|
||||
verticalWidth = (wPitch-1) * Session::getDVerticalPitch () + vWidth;
|
||||
}
|
||||
cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl;
|
||||
|
||||
if (depth != RoutingGauge::nlayerdepth) {
|
||||
horizontalLayer = verticalLayer = Session::getRoutingLayer( depth );
|
||||
|
@ -2947,23 +2636,9 @@ namespace Anabatic {
|
|||
horizontalWidth = verticalWidth = (wPitch-1) * Session::getPitch (depth)
|
||||
+ Session::getWireWidth(depth);
|
||||
} else {
|
||||
if (dir & Flags::Horizontal) {
|
||||
horizontalWidth = Session::getWireWidth ( depth );
|
||||
verticalWidth = Session::getPWireWidth( depth );
|
||||
} else {
|
||||
verticalWidth = Session::getWireWidth ( depth );
|
||||
horizontalWidth = Session::getPWireWidth( depth );
|
||||
}
|
||||
cdebug_log(149,0) << "hW:" << DbU::getValueString(horizontalWidth).c_str()
|
||||
<< "vW:" << DbU::getValueString( verticalWidth).c_str()
|
||||
<< endl;
|
||||
if (dir & Flags::UseNonPref) {
|
||||
cdebug_log(149,0) << "swap H/W width." << endl;
|
||||
std::swap( horizontalWidth, verticalWidth );
|
||||
}
|
||||
horizontalWidth = verticalWidth = Session::getWireWidth( depth );
|
||||
}
|
||||
}
|
||||
cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl;
|
||||
|
||||
AutoSegment* segment;
|
||||
AutoContact* reference = source;
|
||||
|
@ -3063,7 +2738,7 @@ namespace Anabatic {
|
|||
exploreds.insert( seed->getAutoSource() );
|
||||
exploreds.insert( seed->getAutoTarget() );
|
||||
|
||||
if (seed->getAnchoredLength()) {
|
||||
if (seed->getLength()) {
|
||||
if (flags & Flags::Superior) stack.push_back( seed->getAutoTarget() );
|
||||
else stack.push_back( seed->getAutoSource() );
|
||||
} else {
|
||||
|
@ -3088,7 +2763,7 @@ namespace Anabatic {
|
|||
AutoSegment* autoSegment = Session::lookup( segment );
|
||||
if (not autoSegment) continue;
|
||||
|
||||
if (not autoSegment->getAnchoredLength()) {
|
||||
if (not autoSegment->getLength()) {
|
||||
AutoContact* contact = autoSegment->getAutoSource();
|
||||
if (contact and (contact != currentContact)) {
|
||||
if (exploreds.find(contact) == exploreds.end())
|
||||
|
|
|
@ -41,8 +41,8 @@ namespace Anabatic {
|
|||
Segment* AutoVertical::base () { return _vertical; }
|
||||
Segment* AutoVertical::base () const { return _vertical; }
|
||||
Vertical* AutoVertical::getVertical () { return _vertical; }
|
||||
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSource()->getY(); }
|
||||
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTarget()->getY(); }
|
||||
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSourceY(); }
|
||||
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTargetY(); }
|
||||
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
|
||||
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
|
||||
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
|
||||
|
@ -218,15 +218,13 @@ namespace Anabatic {
|
|||
|
||||
if (not gcell) {
|
||||
success = false;
|
||||
if (not isCreated()) {
|
||||
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
|
||||
" begin:%s\n"
|
||||
" end: %s"
|
||||
, getString(this).c_str()
|
||||
, getString(getAutoSource()->getGCell()).c_str()
|
||||
, getString(getAutoTarget()->getGCell()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
|
||||
" begin:%s\n"
|
||||
" end: %s"
|
||||
, getString(this).c_str()
|
||||
, getString(getAutoSource()->getGCell()).c_str()
|
||||
, getString(getAutoTarget()->getGCell()).c_str()
|
||||
) << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -241,8 +239,6 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_tabw(149,-1);
|
||||
|
||||
if (getAutoSource()->isOnPin() or getAutoTarget()->isOnPin()) { cdebug_tabw(149,-1); return false; }
|
||||
|
||||
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Horizontal );
|
||||
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Horizontal );
|
||||
Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax());
|
||||
|
@ -268,13 +264,13 @@ namespace Anabatic {
|
|||
|
||||
if (not isDrag()) {
|
||||
if ( not isStrongTerminal()
|
||||
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < getPitch()*5)) )
|
||||
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
|
||||
{ cdebug_tabw(149,-1); return false; }
|
||||
}
|
||||
|
||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getAnchoredLength() < getPitch()*5) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
|
||||
|
||||
bool success = false;
|
||||
bool sourceSlackened = false;
|
||||
|
@ -382,10 +378,6 @@ namespace Anabatic {
|
|||
if (_vertical->getTargetY() < _vertical->getSourceY()) {
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
_vertical->invert();
|
||||
DbU::Unit duSource = getDuSource();
|
||||
DbU::Unit duTarget = getDuTarget();
|
||||
setDuSource( -duTarget );
|
||||
setDuTarget( -duSource );
|
||||
|
||||
unsigned int spinFlags = _flags & SegDepthSpin;
|
||||
unsetFlags( SegDepthSpin );
|
||||
|
@ -409,8 +401,8 @@ namespace Anabatic {
|
|||
|
||||
void AutoVertical::updatePositions ()
|
||||
{
|
||||
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
|
||||
_sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
||||
}
|
||||
|
||||
|
||||
|
@ -430,8 +422,8 @@ namespace Anabatic {
|
|||
bool AutoVertical::checkPositions () const
|
||||
{
|
||||
bool coherency = true;
|
||||
DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target);
|
||||
DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
||||
|
||||
if ( _sourcePosition != sourcePosition ) {
|
||||
cerr << Error ( "%s\n Source position incoherency: "
|
||||
|
|
|
@ -63,15 +63,13 @@ endif ( CHECK_DETERMINISM )
|
|||
NetBuilderVH.cpp
|
||||
ChipTools.cpp
|
||||
LayerAssign.cpp
|
||||
AntennaProtect.cpp
|
||||
PreRouteds.cpp
|
||||
AnabaticEngine.cpp
|
||||
)
|
||||
set( pyCpps PyAnabatic.cpp
|
||||
)
|
||||
|
||||
set( depLibs ${ETESIAN_LIBRARIES}
|
||||
${CORIOLIS_PYTHON_LIBRARIES}
|
||||
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
|
||||
${CORIOLIS_LIBRARIES}
|
||||
${HURRICANE_PYTHON_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
|
@ -56,7 +55,6 @@ namespace Anabatic {
|
|||
using Hurricane::BasicLayer;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Path;
|
||||
using Hurricane::Occurrence;
|
||||
|
@ -71,28 +69,25 @@ namespace Anabatic {
|
|||
|
||||
|
||||
Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg )
|
||||
: _gdepthv (ndepth)
|
||||
, _gdepthh (ndepth)
|
||||
, _ddepthv (ndepth)
|
||||
, _ddepthh (ndepth)
|
||||
, _ddepthc (ndepth)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps ()
|
||||
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble())
|
||||
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt())
|
||||
, _globalThreshold (0)
|
||||
, _allowedDepth (0)
|
||||
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
|
||||
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
|
||||
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH" , 9.0)->asDouble())
|
||||
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" , -10.0)->asDouble())
|
||||
, _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble())
|
||||
, _edgeHScaling (Cfg::getParamDouble("anabatic.edgeHScaling" , 1.0)->asDouble())
|
||||
, _globalIterations (Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
|
||||
, _diodeName (Cfg::getParamString("etesian.diodeName" , "dio_x0")->asString() )
|
||||
, _antennaGateMaxWL (Cfg::getParamInt ("etesian.antennaGateMaxWL" , 0 )->asInt())
|
||||
, _antennaDiodeMaxWL(Cfg::getParamInt ("etesian.antennaDiodeMaxWL", 0 )->asInt())
|
||||
: _gdepthv (ndepth)
|
||||
, _gdepthh (ndepth)
|
||||
, _ddepthv (ndepth)
|
||||
, _ddepthh (ndepth)
|
||||
, _ddepthc (ndepth)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps ()
|
||||
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble())
|
||||
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt())
|
||||
, _globalThreshold (0)
|
||||
, _allowedDepth (0)
|
||||
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
|
||||
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
|
||||
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH" , 9.0)->asDouble())
|
||||
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" ,-10.0)->asDouble())
|
||||
, _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble())
|
||||
, _edgeHScaling (Cfg::getParamDouble("anabatic.edgeHScaling" , 1.0)->asDouble())
|
||||
, _globalIterations(Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
|
||||
{
|
||||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
|
@ -160,40 +155,29 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_antennaGateMaxWL and not _antennaDiodeMaxWL) {
|
||||
_antennaDiodeMaxWL = _antennaGateMaxWL;
|
||||
cerr << Warning( "Anabatic::Configuration(): \"etesian.antennaGateMaxWL\" is defined but not \"etesian.antennaDiodeMaxWL\".\n"
|
||||
" Setting both to %s"
|
||||
, DbU::getValueString(_antennaGateMaxWL).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Configuration::Configuration ( const Configuration& other )
|
||||
: _gmetalh (other._gmetalh)
|
||||
, _gmetalv (other._gmetalv)
|
||||
, _gcontact (other._gcontact)
|
||||
, _gdepthv (other._gdepthv)
|
||||
, _gdepthh (other._gdepthh)
|
||||
, _ddepthv (other._ddepthv)
|
||||
, _ddepthh (other._ddepthh)
|
||||
, _ddepthc (other._ddepthc)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps (other._extensionCaps)
|
||||
, _saturateRatio (other._saturateRatio)
|
||||
, _globalThreshold (other._globalThreshold)
|
||||
, _allowedDepth (other._allowedDepth)
|
||||
, _edgeCostH (other._edgeCostH)
|
||||
, _edgeCostK (other._edgeCostK)
|
||||
, _edgeHInc (other._edgeHInc)
|
||||
, _edgeHScaling (other._edgeHScaling)
|
||||
, _globalIterations (other._globalIterations)
|
||||
, _diodeName (other._diodeName)
|
||||
, _antennaGateMaxWL (other._antennaGateMaxWL)
|
||||
, _antennaDiodeMaxWL(other._antennaDiodeMaxWL)
|
||||
: _gmetalh (other._gmetalh)
|
||||
, _gmetalv (other._gmetalv)
|
||||
, _gcontact (other._gcontact)
|
||||
, _gdepthv (other._gdepthv)
|
||||
, _gdepthh (other._gdepthh)
|
||||
, _ddepthv (other._ddepthv)
|
||||
, _ddepthh (other._ddepthh)
|
||||
, _ddepthc (other._ddepthc)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps (other._extensionCaps)
|
||||
, _saturateRatio (other._saturateRatio)
|
||||
, _globalThreshold (other._globalThreshold)
|
||||
, _allowedDepth (other._allowedDepth)
|
||||
, _edgeCostH (other._edgeCostH)
|
||||
, _edgeCostK (other._edgeCostK)
|
||||
, _edgeHInc (other._edgeHInc)
|
||||
, _edgeHScaling (other._edgeHScaling)
|
||||
, _globalIterations(other._globalIterations)
|
||||
{
|
||||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
|
@ -302,10 +286,6 @@ namespace Anabatic {
|
|||
{ return getWireWidth( getLayerDepth(layer) ); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getPWireWidth ( const Layer* layer ) const
|
||||
{ return getPWireWidth( getLayerDepth(layer) ); }
|
||||
|
||||
|
||||
Flags Configuration::getDirection ( const Layer* layer ) const
|
||||
{ return getDirection( getLayerDepth(layer) ); }
|
||||
|
||||
|
@ -357,9 +337,6 @@ namespace Anabatic {
|
|||
{ return _rg->getLayerWireWidth(depth); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getPWireWidth ( size_t depth ) const
|
||||
{ return _rg->getLayerPWireWidth(depth); }
|
||||
|
||||
DbU::Unit Configuration::getExtensionCap ( size_t depth ) const
|
||||
{ return _extensionCaps[depth]; }
|
||||
|
||||
|
@ -481,24 +458,13 @@ namespace Anabatic {
|
|||
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
|
||||
for ( Component* component : masterNet->getComponents() ) {
|
||||
cdebug_log(112,0) << "@ " << component << endl;
|
||||
if (not NetExternalComponents::isExternal(component)) {
|
||||
cdebug_log(112,0) << " Not an external component, skip." << endl;
|
||||
continue;
|
||||
}
|
||||
if (not NetExternalComponents::isExternal(component)) continue;
|
||||
|
||||
if (dynamic_cast<Pin*>(component)) {
|
||||
cdebug_log(112,0) << " Pins are always considered best candidates:" << component << endl;
|
||||
bestComponent = component;
|
||||
break;
|
||||
}
|
||||
Segment* segment = dynamic_cast<Segment*>(component);
|
||||
if (not segment) continue;
|
||||
if (segment->getLayer()->getMask() != metal1->getMask()) continue;
|
||||
|
||||
Component* candidate = dynamic_cast<Segment*>(component);
|
||||
if (not candidate
|
||||
or (candidate->getLayer()->getMask() != metal1->getMask()) )
|
||||
candidate = dynamic_cast<Pin*>(component);
|
||||
if (not candidate) continue;
|
||||
|
||||
Box bb = transformation.getBox( candidate->getBoundingBox() );
|
||||
Box bb = transformation.getBox( component->getBoundingBox() );
|
||||
DbU::Unit trackPos = 0;
|
||||
DbU::Unit minPos = DbU::Max;
|
||||
DbU::Unit maxPos = DbU::Min;
|
||||
|
@ -531,7 +497,7 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
|
||||
cdebug_log(112,0) << "| " << transformation << endl;
|
||||
cdebug_log(112,0) << "| " << bb << " of:" << candidate << endl;
|
||||
cdebug_log(112,0) << "| " << bb << " of:" << segment << endl;
|
||||
cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
|
||||
|
||||
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
|
||||
|
@ -590,22 +556,17 @@ namespace Anabatic {
|
|||
Record* Configuration::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
record->add( getSlot( "_gdepthh" , _gdepthh ) );
|
||||
record->add( getSlot( "_gdepthv" , _gdepthv ) );
|
||||
record->add( getSlot( "_rg" , _rg ) );
|
||||
record->add( getSlot( "_gmetalh" , _gmetalh ) );
|
||||
record->add( getSlot( "_gmetalv" , _gmetalv ) );
|
||||
record->add( getSlot( "_gcontact" , _gcontact ) );
|
||||
record->add( getSlot( "_allowedDepth" , _allowedDepth ) );
|
||||
record->add( getSlot( "_edgeCostH" , _edgeCostH ) );
|
||||
record->add( getSlot( "_edgeCostK" , _edgeCostK ) );
|
||||
record->add( getSlot( "_edgeHInc" , _edgeHInc ) );
|
||||
record->add( getSlot( "_edgeHScaling" , _edgeHScaling ) );
|
||||
record->add( getSlot( "_globalIterations", _globalIterations ) );
|
||||
record->add( DbU::getValueSlot( "_antennaGateMaxWL" , &_antennaGateMaxWL ) );
|
||||
record->add( DbU::getValueSlot( "_antennaDiodeMaxWL", &_antennaDiodeMaxWL ) );
|
||||
record->add ( getSlot( "_gdepthh" , _gdepthh ) );
|
||||
record->add ( getSlot( "_gdepthv" , _gdepthv ) );
|
||||
record->add ( getSlot( "_rg" , _rg ) );
|
||||
record->add ( getSlot( "_gmetalh" , _gmetalh ) );
|
||||
record->add ( getSlot( "_gmetalv" , _gmetalv ) );
|
||||
record->add ( getSlot( "_gcontact" , _gcontact ) );
|
||||
record->add ( getSlot( "_allowedDepth", _allowedDepth ) );
|
||||
record->add ( getSlot( "_edgeCostH" , _edgeCostH ) );
|
||||
record->add ( getSlot( "_edgeCostK" , _edgeCostK ) );
|
||||
|
||||
return record;
|
||||
return ( record );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,11 +54,9 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
|
||||
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
||||
// Flags for NetDatas objects states only.
|
||||
const BaseFlags Flags::GlobalFixed = (1L << 5);
|
||||
const BaseFlags Flags::GlobalRouted = (1L << 5);
|
||||
const BaseFlags Flags::GlobalEstimated = (1L << 6);
|
||||
const BaseFlags Flags::GlobalRouted = (1L << 7);
|
||||
const BaseFlags Flags::DetailRouted = (1L << 8);
|
||||
const BaseFlags Flags::ExcludeRoute = (1L << 9);
|
||||
const BaseFlags Flags::ExcludeRoute = (1L << 7);
|
||||
// Masks.
|
||||
const BaseFlags Flags::WestSide = Horizontal|Target;
|
||||
const BaseFlags Flags::EastSide = Horizontal|Source;
|
||||
|
@ -121,10 +119,6 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::NorthPath = (1L << 33);
|
||||
const BaseFlags Flags::UseNonPref = (1L << 34);
|
||||
const BaseFlags Flags::Force = (1L << 35);
|
||||
const BaseFlags Flags::LayerCapOnly = (1L << 36);
|
||||
const BaseFlags Flags::NoMinLength = (1L << 37);
|
||||
const BaseFlags Flags::NoSegExt = (1L << 38);
|
||||
const BaseFlags Flags::NullLength = (1L << 39);
|
||||
|
||||
|
||||
Flags::~Flags ()
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
|
@ -43,7 +42,6 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
|
@ -300,68 +298,52 @@ namespace Anabatic {
|
|||
GCell* c2 = v2->getGCell();
|
||||
|
||||
// Check from GCell 1
|
||||
if ( c1->isNorth(c2) and not v1->isNRestricted() ) restricted = false;
|
||||
else if ( c1->isSouth(c2) and not v1->isSRestricted() ) restricted = false;
|
||||
else if ( c1->isEast (c2) and not v1->isERestricted() ) restricted = false;
|
||||
else if ( c1->isWest (c2) and not v1->isWRestricted() ) restricted = false;
|
||||
// else {
|
||||
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
|
||||
// " v1:%s\n"
|
||||
// " v2:%s"
|
||||
// , getString(v1).c_str()
|
||||
// , getString(v2).c_str()
|
||||
// ) << endl;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (restricted) {
|
||||
cdebug_log(112,0) << "v1 -> v2 edge is restricted." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isVertical() and (c1->getWidth() < hpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 1 is too narrow for V edges." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isHorizontal() and (c1->getHeight() < vpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 1 is too narrow for H edges." << endl;
|
||||
if ( c1->isNorth(c2) ) {
|
||||
if ( !v1->isNRestricted() ) restricted = false;
|
||||
} else if ( c1->isSouth(c2) ) {
|
||||
if ( !v1->isSRestricted() ) restricted = false;
|
||||
} else if ( c1->isEast (c2) ) {
|
||||
if ( !v1->isERestricted() ) restricted = false;
|
||||
} else if ( c1->isWest (c2) ) {
|
||||
if ( !v1->isWRestricted() ) restricted = false;
|
||||
} else {
|
||||
cerr << Error( "GCells are not side by side." ) << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
restricted = true;
|
||||
// Check from GCell 2
|
||||
if ( c2->isNorth(c1) and not v2->isNRestricted() ) restricted = false;
|
||||
else if ( c2->isSouth(c1) and not v2->isSRestricted() ) restricted = false;
|
||||
else if ( c2->isEast (c1) and not v2->isERestricted() ) restricted = false;
|
||||
else if ( c2->isWest (c1) and not v2->isWRestricted() ) restricted = false;
|
||||
// else {
|
||||
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
|
||||
// " v1:%s\n"
|
||||
// " v2:%s"
|
||||
// , getString(v1).c_str()
|
||||
// , getString(v2).c_str()
|
||||
// ) << endl;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (restricted) {
|
||||
cdebug_log(112,0) << "v2 -> v1 edge is restricted." << endl;
|
||||
return true;
|
||||
if ( (c1->getWidth() < hpitch)
|
||||
||(c1->getHeight() < vpitch)
|
||||
||(restricted)
|
||||
) return true;
|
||||
else {
|
||||
restricted = true;
|
||||
// Check from GCell 2
|
||||
if ( c2->isNorth(c1) ) {
|
||||
if ( !v2->isNRestricted() ) restricted = false;
|
||||
} else if ( c2->isSouth(c1) ) {
|
||||
if ( !v2->isSRestricted() ) restricted = false;
|
||||
} else if ( c2->isEast (c1) ) {
|
||||
if ( !v2->isERestricted() ) restricted = false;
|
||||
} else if ( c2->isWest (c1) ) {
|
||||
if ( !v2->isWRestricted() ) restricted = false;
|
||||
} else {
|
||||
cerr << Error( "GCells are not side by side." ) << endl;
|
||||
return true;
|
||||
}
|
||||
if ( (c2->getWidth() < hpitch)
|
||||
||(c2->getHeight() < vpitch)
|
||||
||(restricted)
|
||||
) return true;
|
||||
else {
|
||||
if ((v2->getGCell()->isStrut())){
|
||||
if (e->isMaxCapacity(net)) {
|
||||
cdebug_log(112,0) << "Overcapacity:" << e << endl;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
if ( e->isVertical() and (c2->getWidth() < hpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 2 is too narrow for V edges." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isHorizontal() and (c2->getHeight() < vpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 2 is too narrow for H edges." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( v2->getGCell()->isStrut() and e->isMaxCapacity(net) ) {
|
||||
cdebug_log(112,0) << "Overcapacity:" << e << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1459,10 +1441,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
DbU::Unit Dijkstra::getAntennaGateMaxWL () const
|
||||
{ return _anabatic->getAntennaGateMaxWL(); }
|
||||
|
||||
|
||||
Point Dijkstra::_getPonderedPoint() const
|
||||
{
|
||||
vector<RoutingPad*> rps;
|
||||
|
@ -1484,48 +1462,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void Dijkstra::loadFixedGlobal ( Net* net )
|
||||
{
|
||||
NetData* netData = _anabatic->getNetData( net );
|
||||
netData->setGlobalRouted( true );
|
||||
netData->setGlobalFixed ( true );
|
||||
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
|
||||
if (horizontal) {
|
||||
if (not Session::isGLayer(horizontal->getLayer())) {
|
||||
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
|
||||
" (%s)"
|
||||
, getString(net->getName()).c_str()
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
GCell* begin = _anabatic->getGCellUnder( horizontal->getSource()->getPosition() );
|
||||
GCell* end = _anabatic->getGCellUnder( horizontal->getTarget()->getPosition() );
|
||||
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end) )
|
||||
edge->add( horizontal );
|
||||
}
|
||||
|
||||
Vertical* vertical = dynamic_cast<Vertical*>( component );
|
||||
if (vertical) {
|
||||
if (not Session::isGLayer(vertical->getLayer())) {
|
||||
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
|
||||
" (%s)"
|
||||
, getString(net->getName()).c_str()
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
GCell* begin = _anabatic->getGCellUnder( vertical->getSource()->getPosition() );
|
||||
GCell* end = _anabatic->getGCellUnder( vertical->getTarget()->getPosition() );
|
||||
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end,Flags::NorthPath) )
|
||||
edge->add( vertical );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Dijkstra::load ( Net* net )
|
||||
{
|
||||
_cleanup();
|
||||
|
@ -1537,13 +1473,12 @@ namespace Anabatic {
|
|||
cdebug_log(112,1) << "Dijkstra::load() " << _net << endl;
|
||||
|
||||
vector<RoutingPad*> rps;
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
|
||||
if (state) {
|
||||
if (state->isSelfSym()) {
|
||||
cdebug_log(112,0) << "Dijkstra::SELF SYMMETRY CASE " << DbU::getValueString(state->getSymAxis()) << endl;
|
||||
}
|
||||
state->unsetFlags( NetRoutingState::HasAntenna );
|
||||
}
|
||||
|
||||
for ( Component* component : _net->getComponents() ) {
|
||||
|
@ -1553,24 +1488,20 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(112,0) << "@ frp:" << rp << endl;
|
||||
rps.push_back( rp );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rps.size() < 2) {
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
if (rps.size() < 2) return;
|
||||
|
||||
uint32_t driverCount = 0;
|
||||
for ( auto rp : rps ) {
|
||||
if (not _anabatic->getConfiguration()->selectRpComponent(rp))
|
||||
cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||
|
||||
cdebug_log(112,0) << "@ rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl;
|
||||
Point center = rp->getBoundingBox().getCenter();
|
||||
GCell* gcell = _anabatic->getGCellUnder( center );
|
||||
Box bb = rp->getBoundingBox();
|
||||
bool isDriver = false;
|
||||
Point center = rp->getBoundingBox().getCenter();
|
||||
GCell* gcell = _anabatic->getGCellUnder( center );
|
||||
Box bb = rp->getBoundingBox();
|
||||
|
||||
cdebug_log(112,0) << bb.getXMin() << " " << bb.getXMax() << endl;
|
||||
cdebug_log(112,0) << "center X:" << center.getX() << " gcell Xmax:" << gcell->getXMax() << endl;
|
||||
|
@ -1588,29 +1519,6 @@ namespace Anabatic {
|
|||
continue;
|
||||
}
|
||||
|
||||
Net* rpNet = NULL;
|
||||
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
|
||||
if (plug) {
|
||||
rpNet = plug->getMasterNet();
|
||||
if (rpNet->getDirection() & Net::Direction::DirOut) {
|
||||
cdebug_log(112,0) << "Driver/cell: " << rp << endl;
|
||||
cdebug_log(112,0) << "masterNet: " << rpNet << endl;
|
||||
++driverCount;
|
||||
isDriver = true;
|
||||
}
|
||||
} else {
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getPlugOccurrence().getEntity() );
|
||||
if (pin) {
|
||||
rpNet = pin->getNet();
|
||||
if (rpNet->getDirection() & Net::Direction::DirIn) {
|
||||
cdebug_log(112,0) << "Driver/pin: " << rp << endl;
|
||||
cdebug_log(112,0) << "masterNet: " << rpNet << endl;
|
||||
++driverCount;
|
||||
isDriver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE
|
||||
cdebug_log(112,0) << "| Merged search area: " << _searchArea << ", gcell: " << gcell << endl;
|
||||
|
||||
|
@ -1635,8 +1543,6 @@ namespace Anabatic {
|
|||
vertex->setDegree ( 0 );
|
||||
vertex->setRpCount ( 0 );
|
||||
vertex->setFrom ( NULL );
|
||||
if (isDriver)
|
||||
vertex->setDriver( true );
|
||||
|
||||
vertex->setFrom2 ( NULL);
|
||||
vertex->unsetFlags ( Vertex::UseFromFrom2 );
|
||||
|
@ -1662,45 +1568,6 @@ namespace Anabatic {
|
|||
rp->getBodyHook()->attach( vcontact->getBodyHook() );
|
||||
}
|
||||
|
||||
if (driverCount == 0) {
|
||||
cerr << Error( "Diskstra::load(): Net \"%s\" do not have a driver.\n"
|
||||
, getString(_net->getName()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
if (driverCount > 1) {
|
||||
cerr << Error( "Diskstra::load(): Net \"%s\" have multiple drivers (%u).\n"
|
||||
, getString(_net->getName()).c_str(), driverCount
|
||||
) << endl;
|
||||
}
|
||||
|
||||
if (state and state->isSymmetric() and not state->isSelfSym() and state->isSymMaster()) {
|
||||
if (state->isSymVertical()) {
|
||||
if ( (_searchArea.getXMin() < state->getSymAxis())
|
||||
and (_searchArea.getXMax() > state->getSymAxis()) ) {
|
||||
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
|
||||
" Vertical symmetry axis @%s is inside the net area %s."
|
||||
, getString(_net->getName()).c_str()
|
||||
, getString(state->getSymNet()->getName()).c_str()
|
||||
, DbU::getValueString(state->getSymAxis()).c_str()
|
||||
, getString(_searchArea).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->isSymHorizontal()) {
|
||||
if ( (_searchArea.getYMin() < state->getSymAxis())
|
||||
and (_searchArea.getYMax() > state->getSymAxis()) ) {
|
||||
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
|
||||
" Horizontal symmetry axis @%s is inside the net area %s."
|
||||
, getString(_net->getName()).c_str()
|
||||
, getString(state->getSymNet()->getName()).c_str()
|
||||
, DbU::getValueString(state->getSymAxis()).c_str()
|
||||
, getString(_searchArea).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_searchArea.inflate( _searchAreaHalo );
|
||||
cdebug_log(112,0) << "Search halo: " << DbU::getValueString(_searchAreaHalo) << endl;
|
||||
cdebug_log(112,0) << "Search area: " << _searchArea << endl;
|
||||
|
@ -1849,15 +1716,8 @@ namespace Anabatic {
|
|||
return;
|
||||
}
|
||||
|
||||
Vertex* firstSource = NULL;
|
||||
VertexSet drivers;
|
||||
Vertex* firstSource = NULL;
|
||||
|
||||
for ( Vertex* vertex : _targets ) {
|
||||
if (vertex->isDriver()) drivers.insert( vertex );
|
||||
}
|
||||
if (drivers.empty()) drivers = _targets;
|
||||
|
||||
#if THIS_IS_DISABLED
|
||||
if (_mode & Mode::Monotonic) {
|
||||
if (_targets.size() == 2) {
|
||||
auto ivertex = _targets.begin();
|
||||
|
@ -1874,25 +1734,24 @@ namespace Anabatic {
|
|||
_mode = Mode::Standart;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (not firstSource) {
|
||||
// Standart routing.
|
||||
bool hasDevice = false;
|
||||
for ( Vertex* vertex : drivers ) {
|
||||
if (vertex->getGCell()->isDevice()) hasDevice = true;
|
||||
for ( Vertex* ivertex : _targets ) {
|
||||
if (ivertex->getGCell()->isDevice()) hasDevice = true;
|
||||
}
|
||||
|
||||
Point areaCenter;
|
||||
if (hasDevice) areaCenter = _getPonderedPoint();
|
||||
else areaCenter = _searchArea.getCenter();
|
||||
|
||||
auto ivertex = drivers.begin();
|
||||
auto ivertex = _targets.begin();
|
||||
|
||||
firstSource = *ivertex++;
|
||||
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
|
||||
|
||||
for ( ; ivertex != drivers.end() ; ++ivertex ) {
|
||||
for ( ; ivertex != _targets.end() ; ++ivertex ) {
|
||||
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
|
@ -2201,7 +2060,6 @@ namespace Anabatic {
|
|||
|
||||
if (_sources.size() < 2) { cdebug_tabw(112,-1); return; }
|
||||
|
||||
DbU::Unit gWL = 0;
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
//cerr << "state: " << state << endl;
|
||||
|
||||
|
@ -2232,8 +2090,8 @@ namespace Anabatic {
|
|||
vector<Edge*> aligneds;
|
||||
aligneds.push_back( from );
|
||||
|
||||
Vertex* target = source->getPredecessor();
|
||||
Interval constraint = from->getSide();
|
||||
Vertex* target = source->getPredecessor();
|
||||
Interval constraint = from->getSide();
|
||||
source->setFrom( NULL );
|
||||
|
||||
cdebug_log(112,0) << "| " << target << endl;
|
||||
|
@ -2292,8 +2150,6 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
gWL += segment->getLength();
|
||||
cdebug_log(112,0) << "| ref: " << segment << endl;
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
|
@ -2312,8 +2168,6 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
gWL += segment->getLength();
|
||||
cdebug_log(112,0) << "| ref: " << segment << endl;
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
|
@ -2330,14 +2184,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
if (gWL > getAntennaGateMaxWL()) {
|
||||
cdebug_log(113,0) << "| \"" << _net->getName() << "\" may have antenna effect, "
|
||||
<< DbU::getValueString(gWL)
|
||||
<< endl;
|
||||
if (state)
|
||||
state->setFlags( NetRoutingState::HasAntenna );
|
||||
}
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
@ -2484,66 +2330,51 @@ namespace Anabatic {
|
|||
|
||||
void Dijkstra::_createSelfSymSeg ( Segment* segment )
|
||||
{
|
||||
cdebug_log(112,1) << "Dijkstra::_createSelfSymSeg(): " << segment << endl;
|
||||
|
||||
cdebug_log(112,0) << "void Dijkstra::_createSelfSymSeg ( Segment* segment ): " << _net << ", seg: " << segment << endl;
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
if (state and segment) {
|
||||
//cdebug_log(112,0) << "state: " << state << endl;
|
||||
if ((state != NULL)&&(segment!=NULL)){
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(segment);
|
||||
Vertical* v = dynamic_cast<Vertical *>(segment);
|
||||
Point sp;
|
||||
Point tp;
|
||||
DbU::Unit axis;
|
||||
Component* sourceContact = segment->getSource();
|
||||
Component* targetContact = segment->getTarget();
|
||||
|
||||
cdebug_log(112,0) << "source: " << sourceContact << endl;
|
||||
cdebug_log(112,0) << "target: " << targetContact << endl;
|
||||
cdebug_log(112,0) << "sym axis: " << DbU::getValueString(state->getSymAxis()) << endl;
|
||||
|
||||
if (h) {
|
||||
if (state->isSymHorizontal()) {
|
||||
cdebug_log(112,0) << "Horizontal + Horizontal symmetry." << endl;
|
||||
|
||||
sp = Point( sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
|
||||
tp = Point( targetContact->getX(), state->getSymValue(targetContact->getY()) );
|
||||
axis = state->getSymValue( segment->getY() );
|
||||
} else if (state->isSymVertical()) {
|
||||
cdebug_log(112,0) << "Horizontal + Vertical symmetry." << endl;
|
||||
|
||||
sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() );
|
||||
tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() );
|
||||
Vertical* v = dynamic_cast<Vertical*>(segment);
|
||||
Point sp, tp;
|
||||
DbU::Unit axis;
|
||||
Component* sourceContact = segment->getSource();
|
||||
Component* targetContact = segment->getTarget();
|
||||
if (h){
|
||||
if (state->isSymHorizontal()){
|
||||
cdebug_log(112,0) << "H case Horizontal" << endl;
|
||||
sp = Point(sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
|
||||
tp = Point(targetContact->getX(), state->getSymValue(targetContact->getY()) );
|
||||
axis = state->getSymValue(segment->getY());
|
||||
} else if (state->isSymVertical()){
|
||||
cdebug_log(112,0) << "H case Vertical" << endl;
|
||||
sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() );
|
||||
tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() );
|
||||
axis = segment->getY();
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Horizontal + Unknown symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "sp: " << sp << endl;
|
||||
cdebug_log(112,0) << "tp: " << tp << endl;
|
||||
|
||||
//cerr << "sp: " << sp << endl;
|
||||
//cerr << "tp: " << tp << endl;
|
||||
GCell* sgcell = _anabatic->getGCellUnder( sp );
|
||||
GCell* tgcell = _anabatic->getGCellUnder( tp );
|
||||
|
||||
cdebug_log(112,0) << "GCell: " << sgcell << endl;
|
||||
cdebug_log(112,0) << "GCell: " << tgcell << endl;
|
||||
|
||||
//cerr << "Gcell: " << sgcell << endl;
|
||||
//cerr << "Gcell: " << tgcell << endl;
|
||||
Vertex* svertex = sgcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
Vertex* tvertex = tgcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
|
||||
Contact* sourceSym = NULL;
|
||||
Contact* targetSym = NULL;
|
||||
if (state->isSelfSym()) {
|
||||
cdebug_log(112,0) << "Symmetrical to myself (isSelfSym)." << endl;
|
||||
if (state->isSelfSym()){
|
||||
cdebug_log(112,0) << "isSelfSym" << endl;
|
||||
sourceSym = svertex->getGContact( _net );
|
||||
targetSym = tvertex->getGContact( _net );
|
||||
} else if (state->isSymMaster()){
|
||||
cdebug_log(112,0) << "Symmetrical to (isSymPair): " << state->getSymNet() << endl;
|
||||
cdebug_log(112,0) << "isSymPair: " << state->getSymNet() << endl;
|
||||
sourceSym = svertex->getGContact( state->getSymNet() );
|
||||
targetSym = tvertex->getGContact( state->getSymNet() );
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Unknown Net pairing symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2555,7 +2386,7 @@ namespace Anabatic {
|
|||
, axis
|
||||
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"))
|
||||
);
|
||||
cdebug_log(112,0) << "| dup:" << segment2 << endl;
|
||||
cdebug_log(112,0) << "|| " << segment2 << endl;
|
||||
} else if (v) {
|
||||
if (state->isSymVertical()){
|
||||
//cerr << "V case Vertical" << endl;
|
||||
|
@ -2569,7 +2400,6 @@ namespace Anabatic {
|
|||
axis = segment->getX();
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
GCell* sgcell = _anabatic->getGCellUnder( sp );
|
||||
|
@ -2586,7 +2416,6 @@ namespace Anabatic {
|
|||
targetSym = tvertex->getGContact( state->getSymNet() );
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2601,7 +2430,6 @@ namespace Anabatic {
|
|||
cdebug_log(112,0) << "|| " << segment2 << endl;
|
||||
}
|
||||
}
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,31 +29,16 @@ namespace {
|
|||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
using Anabatic::NetData;
|
||||
using Anabatic::AnabaticEngine;
|
||||
|
||||
|
||||
class SortSegmentByLength {
|
||||
public:
|
||||
inline SortSegmentByLength ( AnabaticEngine* );
|
||||
inline bool operator() ( const Segment*, const Segment* );
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
inline bool operator() ( const Segment*, const Segment* );
|
||||
};
|
||||
|
||||
|
||||
inline SortSegmentByLength::SortSegmentByLength ( AnabaticEngine* anabatic )
|
||||
: _anabatic(anabatic)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool SortSegmentByLength::operator() ( const Segment* lhs, const Segment* rhs )
|
||||
{
|
||||
NetData* lhsNData = _anabatic->getNetData( lhs->getNet() );
|
||||
NetData* rhsNData = _anabatic->getNetData( rhs->getNet() );
|
||||
if (lhsNData->isGlobalFixed() and not rhsNData->isGlobalFixed()) return true;
|
||||
if (rhsNData->isGlobalFixed() and not lhsNData->isGlobalFixed()) return false;
|
||||
|
||||
DbU::Unit delta = rhs->getLength() - lhs->getLength();
|
||||
if (delta > 0) return true;
|
||||
if (delta < 0) return false;
|
||||
|
@ -373,13 +358,12 @@ namespace Anabatic {
|
|||
AnabaticEngine* anabatic = getAnabatic();
|
||||
size_t netCount = 0;
|
||||
|
||||
sort( _segments.begin(), _segments.end(), SortSegmentByLength(anabatic) );
|
||||
sort( _segments.begin(), _segments.end(), SortSegmentByLength() );
|
||||
|
||||
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||
for ( size_t i=0 ; i<_segments.size() ; ) {
|
||||
if (not isEnding(_segments[i])) {
|
||||
NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
|
||||
if (netData->isGlobalFixed ()) break;
|
||||
if (netData->isGlobalRouted()) ++netCount;
|
||||
anabatic->ripup( _segments[i], Flags::Propagate );
|
||||
continue;
|
||||
|
@ -390,7 +374,6 @@ namespace Anabatic {
|
|||
size_t truncate = (size_t)( (getCapacity()*2) / 3 );
|
||||
while ( _segments.size() > truncate ) {
|
||||
NetData* netData = anabatic->getNetData( _segments[truncate]->getNet() );
|
||||
if (netData->isGlobalFixed ()) break;
|
||||
if (netData->isGlobalRouted()) ++netCount;
|
||||
anabatic->ripup( _segments[truncate], Flags::Propagate );
|
||||
}
|
||||
|
|
|
@ -306,7 +306,6 @@ namespace Anabatic {
|
|||
, _fragmentations(new float [_depth])
|
||||
, _globalsCount (new float [_depth])
|
||||
, _key (this,1)
|
||||
, _lastClonedKey (NULL)
|
||||
{
|
||||
if (not _matrixHSide) {
|
||||
_matrixVSide = Session::getSliceHeight();
|
||||
|
@ -476,26 +475,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool GCell::hasNet ( const Net* net ) const
|
||||
{
|
||||
if (hasGContact(net)) return true;
|
||||
|
||||
for ( Edge* edge : _eastEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return true;
|
||||
}
|
||||
}
|
||||
|
||||
for ( Edge* edge : _northEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Contact* GCell::hasGContact ( const Contact* owned ) const
|
||||
{
|
||||
for ( Contact* contact : _gcontacts ) {
|
||||
|
@ -528,22 +507,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
Segment* GCell::hasGoThrough ( Net* net ) const
|
||||
{
|
||||
for ( Edge* edge : _eastEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return segment;
|
||||
}
|
||||
}
|
||||
for ( Edge* edge : _northEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return segment;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Edge* GCell::getEdgeTo ( GCell* neighbor, Flags sideHint ) const
|
||||
{
|
||||
for ( Edge* edge : getEdges(sideHint) ) {
|
||||
|
@ -1349,7 +1312,7 @@ namespace Anabatic {
|
|||
_blockages[depth] += length;
|
||||
_flags |= Flags::Invalidated;
|
||||
|
||||
cdebug_log(149,0) << "GCell::addBlockage() " << this << " "
|
||||
cdebug_log(149,0) << "GCell:addBlockage() " << this << " "
|
||||
<< depth << ":" << DbU::getValueString(_blockages[depth]) << endl;
|
||||
}
|
||||
|
||||
|
@ -1527,14 +1490,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
// Add the blockages.
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
if (not i) continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) {
|
||||
flags() |= Flags::GoStraight;
|
||||
//cerr << "| Set GoStraight on " << this << endl;
|
||||
}
|
||||
}
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i];
|
||||
|
||||
// Compute the number of non pass-through tracks.
|
||||
if (not processeds.empty()) {
|
||||
|
@ -1783,7 +1739,7 @@ namespace Anabatic {
|
|||
|
||||
bool GCell::stepNetDesaturate ( size_t depth, set<Net*>& globalNets, GCell::Set& invalidateds )
|
||||
{
|
||||
cdebug_log(149,0) << "GCell::stepNetDesaturate() depth:" << depth << endl;
|
||||
cdebug_log(9000,0) << "Deter| GCell::stepNetDesaturate() depth:" << depth << endl;
|
||||
cdebug_log(9000,0) << "Deter| " << this << endl;
|
||||
|
||||
updateDensity();
|
||||
|
@ -1805,7 +1761,7 @@ namespace Anabatic {
|
|||
if (segmentDepth < depth) continue;
|
||||
if (segmentDepth > depth) break;
|
||||
|
||||
cdebug_log(149,0) << "Move up " << (*isegment) << endl;
|
||||
cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl;
|
||||
|
||||
if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds))
|
||||
return true;
|
||||
|
@ -1870,7 +1826,7 @@ namespace Anabatic {
|
|||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer();
|
||||
s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add( DbU::getValueSlot( s.str(), &_blockages[depth] ) );
|
||||
record->add( getSlot ( s.str(), &_blockages[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
|
|
|
@ -335,55 +335,9 @@ namespace Anabatic {
|
|||
|
||||
cmess1 << " o Desaturate layer "
|
||||
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
|
||||
cdebug_log(149,0) << "Session::getSaturateRatio()=" << Session::getSaturateRatio() << endl;
|
||||
|
||||
GCellKeyQueue queue;
|
||||
GCell::Set invalidateds;
|
||||
|
||||
for ( GCell* gcell : getGCells() ) queue.push( gcell->cloneKey(depth) );
|
||||
|
||||
bool optimized = true;
|
||||
bool finished = false;
|
||||
while ( optimized ) {
|
||||
Session::revalidate ();
|
||||
optimized = false;
|
||||
|
||||
while ( not queue.empty() ) {
|
||||
GCell::Key* topKey = queue.top();
|
||||
GCell* gcell = const_cast<GCell*>( topKey->getGCell() );
|
||||
queue.pop();
|
||||
|
||||
if (topKey->isActive()) {
|
||||
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
|
||||
<< gcell->getDensity(depth) << " " << gcell << endl;
|
||||
|
||||
if (not gcell->isSaturated(depth)) {
|
||||
cdebug_log(149,0) << "STOP desaturated: " << gcell << endl;
|
||||
finished = true;
|
||||
} else {
|
||||
if (finished) {
|
||||
cparanoid << "[ERROR] Still saturated: " << gcell << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (not finished) {
|
||||
optimized = gcell->stepNetDesaturate( depth, globalNets, invalidateds );
|
||||
if (optimized) {
|
||||
for ( GCell* gcell : invalidateds ) {
|
||||
queue.push( gcell->cloneKey(depth) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete topKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if OLD_QUEUE_DISABLED
|
||||
GCellDensitySet queue ( depth, getGCells() );
|
||||
GCell::Set invalidateds;
|
||||
GCell::Set invalidateds;
|
||||
|
||||
bool optimized = true;
|
||||
while ( optimized ) {
|
||||
|
@ -417,7 +371,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -754,7 +707,7 @@ namespace Anabatic {
|
|||
if (not segment->isStrongTerminal()) locals.push_back( segment );
|
||||
continue;
|
||||
}
|
||||
if ( (segment->getAnchoredLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
|
||||
if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
|
||||
locals.push_back( segment );
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -228,44 +228,22 @@ namespace Anabatic {
|
|||
|
||||
void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target )
|
||||
{
|
||||
Segment* segment = dynamic_cast<Segment*>( anchor );
|
||||
Segment* segment = dynamic_cast<Segment*>( anchor );
|
||||
if (segment) {
|
||||
source = segment->getSourcePosition();
|
||||
target = segment->getTargetPosition();
|
||||
} else {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
|
||||
if (rp) {
|
||||
source = rp->getSourcePosition();
|
||||
target = rp->getTargetPosition();
|
||||
} else {
|
||||
source = anchor->getPosition();
|
||||
target = anchor->getPosition();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == target) return;
|
||||
if (source.getX() > target.getX()) swap( source, target );
|
||||
if (source.getY() > target.getY()) swap( source, target );
|
||||
|
||||
if (not Session::getRoutingGauge()->isSymbolic()) {
|
||||
size_t rpDepth = Session::getLayerDepth( anchor->getLayer() );
|
||||
Flags direction = Session::getDirection ( rpDepth );
|
||||
DbU::Unit wwidth = Session::getWireWidth (rpDepth) / 2;
|
||||
cdebug_log(145,0) << "Not a symbolic gauge, shrink positions of " << DbU::getValueString(wwidth) << endl;
|
||||
if (rpDepth == 0) return;
|
||||
if (direction.contains(Flags::Horizontal)) {
|
||||
cdebug_log(145,0) << "H shrink" << endl;
|
||||
source.translate( wwidth, 0 );
|
||||
target.translate( -wwidth, 0 );
|
||||
} else {
|
||||
cdebug_log(145,0) << "V shrink" << endl;
|
||||
source.translate( 0, wwidth );
|
||||
target.translate( 0, -wwidth );
|
||||
}
|
||||
} else {
|
||||
cdebug_log(145,0) << "Symbolic gauge, no shrink" << endl;
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
|
||||
if (rp) {
|
||||
source = rp->getSourcePosition();
|
||||
target = rp->getTargetPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
source = anchor->getPosition();
|
||||
target = anchor->getPosition();
|
||||
}
|
||||
|
||||
|
||||
|
@ -423,14 +401,14 @@ namespace Anabatic {
|
|||
for ( Hook* hook : fromHook->getHooks() ) {
|
||||
cdebug_log(145,0) << "Hook: " << hook << endl;
|
||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||
<< "[" << (int)_connexity.fields.globals
|
||||
<< "+" << (int)_connexity.fields.M1
|
||||
<< "+" << (int)_connexity.fields.M2
|
||||
<< "+" << (int)_connexity.fields.M3
|
||||
<< "+" << (int)_connexity.fields.Pin
|
||||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
<< "[" << (int)_connexity.fields.globals
|
||||
<< "+" << (int)_connexity.fields.M1
|
||||
<< "+" << (int)_connexity.fields.M2
|
||||
<< "+" << (int)_connexity.fields.M3
|
||||
<< "+" << (int)_connexity.fields.Pin
|
||||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
|
||||
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
|
||||
if (toSegment) {
|
||||
|
@ -529,16 +507,6 @@ namespace Anabatic {
|
|||
|
||||
if (_gcell == NULL) throw Error( missingGCell );
|
||||
|
||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||
<< "[" << (int)_connexity.fields.globals
|
||||
<< "+" << (int)_connexity.fields.M1
|
||||
<< "+" << (int)_connexity.fields.M2
|
||||
<< "+" << (int)_connexity.fields.M3
|
||||
<< "+" << (int)_connexity.fields.Pin
|
||||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -575,15 +543,6 @@ namespace Anabatic {
|
|||
void NetBuilder::construct ()
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
|
||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||
<< "[" << (int)_connexity.fields.globals
|
||||
<< "+" << (int)_connexity.fields.M1
|
||||
<< "+" << (int)_connexity.fields.M2
|
||||
<< "+" << (int)_connexity.fields.M3
|
||||
<< "+" << (int)_connexity.fields.Pin
|
||||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
|
||||
if (not isTwoMetals()) {
|
||||
_southWestContact = NULL;
|
||||
|
@ -603,11 +562,7 @@ namespace Anabatic {
|
|||
case Conn_1G_2M1:
|
||||
case Conn_1G_3M1:
|
||||
case Conn_1G_4M1:
|
||||
case Conn_1G_5M1:
|
||||
case Conn_1G_6M1:
|
||||
case Conn_1G_7M1:
|
||||
case Conn_1G_8M1:
|
||||
case Conn_1G_9M1: _do_1G_xM1(); break;
|
||||
case Conn_1G_5M1: _do_1G_xM1(); break;
|
||||
// End 1G_xM1 cascaded cases.
|
||||
|
||||
case Conn_1G_1M2:
|
||||
|
@ -627,31 +582,17 @@ namespace Anabatic {
|
|||
case Conn_2G_3M1:
|
||||
case Conn_2G_4M1:
|
||||
case Conn_2G_5M1:
|
||||
case Conn_2G_6M1:
|
||||
case Conn_2G_7M1:
|
||||
case Conn_2G_8M1:
|
||||
case Conn_2G_9M1:
|
||||
case Conn_3G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_3G_2M1:
|
||||
case Conn_3G_3M1:
|
||||
case Conn_3G_4M1:
|
||||
case Conn_3G_5M1:
|
||||
case Conn_3G_6M1:
|
||||
case Conn_3G_7M1:
|
||||
case Conn_3G_8M1:
|
||||
case Conn_3G_9M1:
|
||||
case Conn_3G_2M3:
|
||||
case Conn_3G_3M3:
|
||||
case Conn_3G_4M3:
|
||||
case Conn_4G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_4G_2M1:
|
||||
case Conn_4G_3M1:
|
||||
case Conn_4G_4M1:
|
||||
case Conn_4G_5M1:
|
||||
case Conn_4G_6M1:
|
||||
case Conn_4G_7M1:
|
||||
case Conn_4G_8M1:
|
||||
case Conn_4G_9M1: _do_xG_xM1_xM3(); break;
|
||||
case Conn_4G_4M1: _do_xG_xM1_xM3(); break;
|
||||
// End xG_xM1_xM3 cascaded cases.
|
||||
|
||||
case Conn_4G_1M2: if (_do_4G_1M2()) break;
|
||||
|
@ -675,28 +616,17 @@ namespace Anabatic {
|
|||
case Conn_4G: _do_xG(); break;
|
||||
// End xG cascaded cases.
|
||||
// Optimized specific cases.
|
||||
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
|
||||
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
|
||||
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
||||
case Conn_2G_1PinM2:
|
||||
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
||||
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
|
||||
case Conn_2G_1PinM3:
|
||||
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break;
|
||||
case Conn_1G_1M1_1PinM3: _do_1G_1M1_1PinM3(); break;
|
||||
case Conn_1G_1M1_1PinM2:
|
||||
case Conn_1G_2M1_1PinM2: _do_1G_xM1_1PinM2(); break;
|
||||
case Conn_2G_1M1_1PinM2:
|
||||
case Conn_2G_2M1_1PinM2: _do_2G_xM1_1PinM2(); break;
|
||||
case Conn_2G_1M1_1PinM3:
|
||||
case Conn_2G_2M1_1PinM3:
|
||||
case Conn_2G_3M1_1PinM3: _do_2G_xM1_1PinM3(); break;
|
||||
case Conn_3G_1M1_1PinM3:
|
||||
case Conn_3G_2M1_1PinM3:
|
||||
case Conn_3G_3M1_1PinM3: _do_3G_xM1_1PinM3(); break;
|
||||
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2 (); break;
|
||||
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
|
||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
|
||||
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
|
||||
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
|
||||
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
||||
case Conn_2G_1PinM2:
|
||||
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
||||
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
|
||||
case Conn_2G_1PinM3:
|
||||
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break;
|
||||
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break;
|
||||
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
|
||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break;
|
||||
default:
|
||||
if (not isTwoMetals())
|
||||
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
||||
|
@ -1138,42 +1068,7 @@ namespace Anabatic {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_1M1_1PinM3 ()
|
||||
{
|
||||
throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_xM1_1PinM2 ()
|
||||
{
|
||||
throw Error ( "%s::_do_1G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G_xM1_1PinM2 ()
|
||||
{
|
||||
throw Error ( "%s::_do_2G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G_xM1_1PinM3 ()
|
||||
{
|
||||
throw Error ( "%s::_do_2G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_3G_xM1_1PinM3 ()
|
||||
{
|
||||
throw Error ( "%s::_do_3G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_globalSegment ()
|
||||
{
|
||||
throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
|
@ -2366,10 +2261,8 @@ namespace Anabatic {
|
|||
size_t degree = routingPads.getSize();
|
||||
|
||||
if (degree == 0) {
|
||||
if (not net->isBlockage()) {
|
||||
cmess2 << Warning( "Net \"%s\" do not have any RoutingPad (ignored)."
|
||||
, getString(net->getName()).c_str() ) << endl;
|
||||
}
|
||||
cmess2 << Warning("Net \"%s\" do not have any RoutingPad (ignored)."
|
||||
,getString(net->getName()).c_str()) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,9 @@ namespace Anabatic {
|
|||
|
||||
getPositions( rp, sourcePosition, targetPosition );
|
||||
|
||||
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
|
||||
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
|
||||
|
||||
GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition );
|
||||
GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition );
|
||||
|
||||
|
@ -108,53 +111,6 @@ namespace Anabatic {
|
|||
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
Box rpBb = rp->getBoundingBox();
|
||||
if (rpDepth != 0) {
|
||||
DbU::Unit hborder = 0;
|
||||
DbU::Unit vborder = 0;
|
||||
if (direction.contains(Flags::Horizontal)) {
|
||||
vborder = Session::getWireWidth(rpDepth) / 2;
|
||||
rpBb.inflate( hborder, vborder );
|
||||
if (not rpBb.isEmpty()) {
|
||||
DbU::Unit trackAxis = Session::getNearestTrackAxis( rp->getLayer()
|
||||
, sourcePosition.getY()
|
||||
, Constant::Nearest );
|
||||
if (trackAxis != sourcePosition.getY()) {
|
||||
cerr << Warning( "NetBuilderHV::doRp_AutoContacts(): Adjust Y position to nearest H track of %s\n"
|
||||
" (%s -> %s)"
|
||||
, getString(rp).c_str()
|
||||
, DbU::getValueString(sourcePosition.getY()).c_str()
|
||||
, DbU::getValueString(trackAxis).c_str()
|
||||
) << endl;
|
||||
sourcePosition.setY( trackAxis );
|
||||
targetPosition.setY( trackAxis );
|
||||
}
|
||||
} else {
|
||||
cdebug_log(145,0) << "rpBb is too narrow to adjust: " << rp->getBoundingBox() << endl;
|
||||
}
|
||||
} else {
|
||||
hborder = Session::getWireWidth(rpDepth) / 2;
|
||||
rpBb.inflate( hborder, vborder );
|
||||
if (not rpBb.isEmpty()) {
|
||||
DbU::Unit trackAxis = Session::getNearestTrackAxis( rp->getLayer()
|
||||
, sourcePosition.getX()
|
||||
, Constant::Nearest );
|
||||
if (trackAxis != sourcePosition.getX()) {
|
||||
cerr << Warning( "NetBuilderHV::doRp_AutoContacts(): Adjust X position to nearest V track of %s\n"
|
||||
" (%s -> %s)"
|
||||
, getString(rp).c_str()
|
||||
, DbU::getValueString(sourcePosition.getX()).c_str()
|
||||
, DbU::getValueString(trackAxis).c_str()
|
||||
) << endl;
|
||||
sourcePosition.setX( trackAxis );
|
||||
targetPosition.setX( trackAxis );
|
||||
}
|
||||
} else {
|
||||
cdebug_log(145,0) << "rpBb is too narrow to adjust: " << rp->getBoundingBox() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
|
@ -212,9 +168,9 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
AutoContact* rpSourceContact;
|
||||
AutoContact* rpContactTarget;
|
||||
|
||||
Flags useNonPref = Flags::NoFlags;
|
||||
if (flags & UseNonPref) useNonPref |= Flags::UseNonPref;
|
||||
|
@ -283,22 +239,6 @@ namespace Anabatic {
|
|||
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
|
||||
} else {
|
||||
#if OFFGRID_M2_DISABLED
|
||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||
RoutingLayerGauge* lgM2 = Session::getLayerGauge( 1 );
|
||||
DbU::Unit trackAxis = lgM2->getTrackPosition( cellAb.getYMin()
|
||||
, cellAb.getYMax()
|
||||
, rp->getY()
|
||||
, Constant::Nearest );
|
||||
bool offGrid = (trackAxis != rp->getY());
|
||||
if (offGrid) {
|
||||
cdebug_log(145,0) << "Off grid, Misaligned M2 RoutingPad, add vertical strap" << endl;
|
||||
subContact1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
|
||||
rpSourceContact = subContact1;
|
||||
}
|
||||
#endif
|
||||
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
|
||||
}
|
||||
|
@ -311,79 +251,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderHV::doRp_AccessNorthPin ( GCell* gcell, RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl;
|
||||
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
AutoContact* turn = NULL;
|
||||
|
||||
doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect );
|
||||
|
||||
Net* net = rp->getNet();
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||
if (pinDir == Pin::AccessDirection::NORTH) {
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getRoutingLayer(1) );
|
||||
AutoSegment* segment = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||
segment->setAxis( rp->getX(), Flags::Force );
|
||||
segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||
rpSourceContact = turn;
|
||||
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) );
|
||||
segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||
rpSourceContact = turn;
|
||||
|
||||
DbU::Unit axis = gcell->getYMax() - Session::getDHorizontalPitch();
|
||||
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||
|
||||
segment->setAxis( axis, Flags::Force );
|
||||
//segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||
cdebug_log(145,0) << segment << endl;
|
||||
} else {
|
||||
turn = rpSourceContact;
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return turn;
|
||||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderHV::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl;
|
||||
|
||||
Net* net = rp->getNet();
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
AutoContact* turn = NULL;
|
||||
AutoSegment* segment = NULL;
|
||||
|
||||
doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect );
|
||||
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) );
|
||||
segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||
segment->setAxis( pin->getCenter().getY(), Flags::Force );
|
||||
|
||||
rpSourceContact = turn;
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) );
|
||||
segment = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||
|
||||
DbU::Unit axis = 0;
|
||||
if (pinDir == Pin::AccessDirection::EAST)
|
||||
axis = gcell->getXMax() - Session::getDVerticalPitch();
|
||||
else
|
||||
axis = gcell->getXMin() + Session::getDVerticalPitch();
|
||||
segment->setAxis( axis );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return turn;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_1G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
@ -620,7 +487,7 @@ namespace Anabatic {
|
|||
|
||||
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoFlags );
|
||||
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, turn1, Flags::Horizontal );
|
||||
|
||||
if (east() or west()) {
|
||||
|
@ -805,17 +672,9 @@ namespace Anabatic {
|
|||
AutoSegment* vertical = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||
rpSourceContact = turn;
|
||||
|
||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||
RoutingLayerGauge* lgM3 = Session::getLayerGauge( 2 );
|
||||
DbU::Unit axis = lgM3->getTrackPosition( cellAb.getXMin()
|
||||
, cellAb.getXMax()
|
||||
, getGCell()->getXMax() - Session::getDVerticalPitch()
|
||||
, Constant::Superior );
|
||||
DbU::Unit axis = getGCell()->getXMax() - Session::getDVerticalPitch();
|
||||
if (pinDir == Pin::AccessDirection::WEST)
|
||||
axis = lgM3->getTrackPosition( cellAb.getXMin()
|
||||
, cellAb.getXMax()
|
||||
, getGCell()->getXMin() + Session::getDVerticalPitch()
|
||||
, Constant::Inferior );
|
||||
axis = getGCell()->getXMin() + Session::getDVerticalPitch();
|
||||
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||
|
||||
vertical->setAxis( axis, Flags::Force );
|
||||
|
@ -871,9 +730,6 @@ namespace Anabatic {
|
|||
AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( htee1, htee2, Flags::Horizontal );
|
||||
|
||||
if (pinDir == Pin::AccessDirection::EAST)
|
||||
std::swap( htee1, htee2 );
|
||||
|
||||
setSouthWestContact( htee1 );
|
||||
setNorthEastContact( htee2 );
|
||||
}
|
||||
|
@ -888,8 +744,9 @@ namespace Anabatic {
|
|||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
|
||||
rpSourceContact = doRp_AccessNorthPin( getGCell(), getRoutingPads()[0] );
|
||||
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoFlags );
|
||||
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
|
||||
|
@ -947,28 +804,19 @@ namespace Anabatic {
|
|||
|
||||
setSouthWestContact( turn1 );
|
||||
setNorthEastContact( htee1 );
|
||||
} else if (north() and south()) {
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
|
||||
|
||||
} else {
|
||||
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( turn1, vtee1, Flags::Horizontal );
|
||||
AutoSegment::create( rpSourceContact, vtee1, Flags::Vertical );
|
||||
|
||||
setBothCornerContacts( vtee1 );
|
||||
} else { // Remaining case is East & West.
|
||||
AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, htee1, Flags::Vertical );
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( vtee1, turn1, Flags::Vertical );
|
||||
|
||||
setBothCornerContacts( htee1 );
|
||||
setSouthWestContact( vtee1 );
|
||||
setNorthEastContact( turn1 );
|
||||
}
|
||||
} else {
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1, turn2, Flags::Horizontal );
|
||||
|
||||
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( turn2, vtee1, Flags::Vertical );
|
||||
AutoSegment::create( rpSourceContact, vtee1, Flags::Vertical );
|
||||
|
||||
AutoContact* vtee2 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( vtee1, vtee2, Flags::Vertical );
|
||||
|
@ -982,258 +830,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_2G_xM1_1PinM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G_xM1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
RoutingPad* pinM3 = NULL;
|
||||
AutoContact* pinContact = NULL;
|
||||
AutoContact* dummy = NULL;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
|
||||
vector<RoutingPad*> rpsM1;
|
||||
for ( RoutingPad* rp : getRoutingPads() ) {
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) pinM3 = rp;
|
||||
else rpsM1.push_back( rp );
|
||||
}
|
||||
|
||||
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
doRp_AutoContacts( getGCell(), pinM3, pinContact, dummy, NoFlags );
|
||||
|
||||
AutoContact* m1contact = doRp_Access( getGCell(), rpsM1.back(), HAccess );
|
||||
|
||||
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( m1contact , vtee1, Flags::Horizontal );
|
||||
AutoSegment::create( pinContact, vtee1, Flags::Vertical );
|
||||
|
||||
AutoContact* vtee2 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( vtee1, vtee2, Flags::Vertical );
|
||||
|
||||
setBothCornerContacts( vtee2 );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_3G_xM1_1PinM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_3G_1M1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
RoutingPad* pinM3 = NULL;
|
||||
AutoContact* pinContact = NULL;
|
||||
AutoContact* dummy = NULL;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
|
||||
vector<RoutingPad*> rpsM1;
|
||||
for ( RoutingPad* rp : getRoutingPads() ) {
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) pinM3 = rp;
|
||||
else rpsM1.push_back( rp );
|
||||
}
|
||||
|
||||
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
doRp_AutoContacts( getGCell(), pinM3, pinContact, dummy, NoFlags );
|
||||
|
||||
AutoContact* m1contact = doRp_Access( getGCell(), rpsM1.back(), HAccess );
|
||||
|
||||
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( m1contact , vtee1, Flags::Horizontal );
|
||||
|
||||
AutoContact* vtee2 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( vtee1, vtee2, Flags::Vertical );
|
||||
|
||||
AutoContact* vtee3 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( vtee2, vtee3, Flags::Vertical );
|
||||
|
||||
if (not south() or not north()) {
|
||||
AutoSegment::create( pinContact, vtee1, Flags::Vertical );
|
||||
}
|
||||
|
||||
if (not east() or not west()) {
|
||||
AutoSegment::create( pinContact, vtee2, Flags::Horizontal );
|
||||
}
|
||||
|
||||
if (not south()) {
|
||||
setSouthWestContact( vtee2 );
|
||||
setNorthEastContact( vtee3 );
|
||||
} else if (not north()) {
|
||||
setSouthWestContact( vtee3 );
|
||||
setNorthEastContact( vtee2 );
|
||||
} else if (not east()) {
|
||||
setSouthWestContact( vtee3 );
|
||||
setNorthEastContact( vtee1 );
|
||||
} else if (not west()) {
|
||||
setSouthWestContact( vtee1 );
|
||||
setNorthEastContact( vtee3 );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_1G_xM1_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
|
||||
vector<RoutingPad*> rpsM1;
|
||||
RoutingPad* pinM2 = NULL;
|
||||
for ( RoutingPad* rp : getRoutingPads() ) {
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) pinM2 = rp;
|
||||
else rpsM1.push_back( rp );
|
||||
}
|
||||
|
||||
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
AutoContact* turn = NULL;
|
||||
AutoContact* tee = NULL;
|
||||
AutoContact* pinM2Contact = NULL;
|
||||
AutoContact* rpM1Contact = NULL;
|
||||
doRp_AutoContacts( getGCell(), pinM2, pinM2Contact, rpM1Contact, NoProtect );
|
||||
rpM1Contact = doRp_Access( getGCell(), rpsM1[0], (north() or south()) ? HAccess : NoFlags );
|
||||
|
||||
if (north() or south()) {
|
||||
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( rpM1Contact , tee , Flags::Horizontal );
|
||||
AutoSegment::create( pinM2Contact, turn, Flags::Horizontal );
|
||||
AutoSegment::create( tee , turn, Flags::Vertical );
|
||||
|
||||
setBothCornerContacts( tee );
|
||||
} else {
|
||||
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( rpM1Contact , tee , Flags::Vertical );
|
||||
AutoSegment::create( pinM2Contact, tee , Flags::Horizontal );
|
||||
AutoSegment::create( tee , turn, Flags::Vertical );
|
||||
|
||||
setBothCornerContacts( turn );
|
||||
}
|
||||
|
||||
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_2G_xM1_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
|
||||
vector<RoutingPad*> rpsM1;
|
||||
RoutingPad* pinM2 = NULL;
|
||||
for ( RoutingPad* rp : getRoutingPads() ) {
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) pinM2 = rp;
|
||||
else rpsM1.push_back( rp );
|
||||
}
|
||||
|
||||
AutoContact* pinM2Contact = NULL;
|
||||
AutoContact* rpM1Contact = NULL;
|
||||
doRp_AutoContacts( getGCell(), pinM2, pinM2Contact, rpM1Contact, NoFlags );
|
||||
rpM1Contact = doRp_Access( getGCell(), rpsM1[0], NoFlags );
|
||||
|
||||
if (north() and south()) {
|
||||
cdebug_log(145,0) << "Case north & south." << endl;
|
||||
AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* vtee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( pinM2Contact, htee, Flags::Horizontal );
|
||||
AutoSegment::create( rpM1Contact , htee, Flags::Vertical );
|
||||
AutoSegment::create( htee , vtee, Flags::Horizontal );
|
||||
setBothCornerContacts( vtee );
|
||||
} else if (east() and west()) {
|
||||
cdebug_log(145,0) << "Case east & west." << endl;
|
||||
AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( pinM2Contact, htee1, Flags::Horizontal );
|
||||
AutoSegment::create( rpM1Contact , htee1, Flags::Vertical );
|
||||
AutoSegment::create( htee1 , turn , Flags::Horizontal );
|
||||
AutoSegment::create( htee2 , turn , Flags::Vertical );
|
||||
setBothCornerContacts( htee2 );
|
||||
} else {
|
||||
cdebug_log(145,0) << "Case bend." << endl;
|
||||
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( pinM2Contact, vtee1, Flags::Horizontal );
|
||||
AutoSegment::create( rpM1Contact , vtee1, Flags::Vertical );
|
||||
AutoSegment::create( vtee1 , turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , htee2, Flags::Horizontal );
|
||||
setBothCornerContacts( htee2 );
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "Wiring all M1 together." << endl;
|
||||
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_1G_1M1_1PinM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
|
||||
RoutingPad* pinM3 = getRoutingPads()[0];
|
||||
RoutingPad* rpM1 = getRoutingPads()[1];
|
||||
if (dynamic_cast<Pin*>(rpM1->getOccurrence().getEntity())) std::swap( rpM1, pinM3 );
|
||||
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), rpM1, HAccess );
|
||||
AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( contact1, htee, Flags::Horizontal );
|
||||
|
||||
rpSourceContact = doRp_AccessNorthPin( getGCell(), pinM3 );
|
||||
|
||||
if (north() or south()) {
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||
AutoSegment::create( turn , htee, Flags::Horizontal );
|
||||
} else {
|
||||
AutoSegment::create( rpSourceContact, htee, Flags::Vertical );
|
||||
}
|
||||
setBothCornerContacts( htee );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_2G_1M1 ()
|
||||
{
|
||||
return _do_xG_1M1();
|
||||
|
@ -1258,12 +854,9 @@ namespace Anabatic {
|
|||
if (getConnexity().fields.globals == 2) {
|
||||
if (north() and south()) {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal );
|
||||
contact1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal );
|
||||
setNorthEastContact( contact1 );
|
||||
setSouthWestContact( contact2 );
|
||||
setBothCornerContacts( contact2 );
|
||||
} else if (east() and west()) {
|
||||
// AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
|
||||
// AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
|
@ -1623,20 +1216,6 @@ namespace Anabatic {
|
|||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
|
||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||
RoutingLayerGauge* lgM3 = Session::getLayerGauge( 2 );
|
||||
DbU::Unit trackAxis = lgM3->getTrackPosition( cellAb.getXMin()
|
||||
, cellAb.getXMax()
|
||||
, getRoutingPads()[0]->getX()
|
||||
, Constant::Nearest );
|
||||
bool offGrid = (trackAxis != getRoutingPads()[0]->getX());
|
||||
if (offGrid) {
|
||||
cdebug_log(145,0) << "Off grid, Misaligned M3, add horizontal strap" << endl;
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Horizontal );
|
||||
setBothCornerContacts( turn1 );
|
||||
}
|
||||
|
||||
if (flags & HAccess) {
|
||||
// HARDCODED VALUE.
|
||||
if (getRoutingPads()[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) {
|
||||
|
@ -1646,15 +1225,14 @@ namespace Anabatic {
|
|||
setBothCornerContacts( subContact );
|
||||
}
|
||||
} else {
|
||||
if (getSourceContact() and (getSourceContact()->getX() != getSouthWestContact()->getX())) {
|
||||
cdebug_log(145,0) << "On grid, Misaligned M3, add dogleg" << endl;
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment* v1 = AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1, turn2, Flags::Horizontal );
|
||||
v1->setAxis( getSouthWestContact()->getX(), Flags::Force );
|
||||
v1->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||
setBothCornerContacts( turn2 );
|
||||
if (getSourceContact()) {
|
||||
if (getSourceContact()->getX() != getSouthWestContact()->getX()) {
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
||||
setBothCornerContacts( turn2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
|
@ -1751,7 +1329,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
|
@ -1771,135 +1349,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void NetBuilderHV::singleGCell ( AnabaticEngine* anbt, Net* net )
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilderHV::singleGCell() " << net << endl;
|
||||
|
||||
vector<RoutingPad*> rpM1s;
|
||||
Component* rpM2 = NULL;
|
||||
RoutingPad* rpPin = NULL;
|
||||
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) {
|
||||
rpPin = rp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 1)
|
||||
rpM2 = rp;
|
||||
else
|
||||
rpM1s.push_back( rp );
|
||||
}
|
||||
|
||||
if ( (rpM1s.size() < 2) and not (rpM2 or rpPin) ) {
|
||||
cerr << Error( "For %s, less than two Plugs/Pins (%d)."
|
||||
, getString(net).c_str()
|
||||
, rpM1s.size() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rpM1s.empty()) {
|
||||
cerr << Error( "No METAL1 in Single GCell for Net \"%s\".", getString(net->getName()).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
sortRpByX( rpM1s, NetBuilder::NoFlags ); // increasing X.
|
||||
|
||||
GCell* gcell1 = anbt->getGCellUnder( (*rpM1s.begin ())->getCenter() );
|
||||
GCell* gcell2 = anbt->getGCellUnder( (*rpM1s.rbegin())->getCenter() );
|
||||
|
||||
if (not gcell1) {
|
||||
cerr << Error( "No GCell under %s.", getString(*(rpM1s.begin())).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
if (gcell1 != gcell2) {
|
||||
cerr << Error( "Not under a single GCell %s.", getString(*(rpM1s.rbegin())).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "singleGCell " << gcell1 << endl;
|
||||
|
||||
AutoContact* turn1 = NULL;
|
||||
AutoContact* turn2 = NULL;
|
||||
AutoContact* source = NULL;
|
||||
AutoContact* target = NULL;
|
||||
|
||||
for ( size_t irp=1 ; irp<rpM1s.size() ; ++irp ) {
|
||||
doRp_AutoContacts( gcell1, rpM1s[irp-1], source, turn1, DoSourceContact );
|
||||
doRp_AutoContacts( gcell1, rpM1s[irp ], target, turn1, DoSourceContact );
|
||||
|
||||
if (source->getUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) {
|
||||
uint64_t flags = checkRoutingPadSize( rpM1s[irp-1] );
|
||||
if ((flags & VSmall) or Session::getConfiguration()->isVH()) {
|
||||
if (Session::getConfiguration()->isHV()) {
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( source, turn1, Flags::Horizontal );
|
||||
source = turn1;
|
||||
}
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( source, turn1 , Flags::Vertical );
|
||||
source = turn1;
|
||||
}
|
||||
flags = checkRoutingPadSize( rpM1s[irp] );
|
||||
if ((flags & VSmall) or Session::getConfiguration()->isVH()) {
|
||||
if (Session::getConfiguration()->isHV()) {
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( target, turn1, Flags::Horizontal );
|
||||
target = turn1;
|
||||
}
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( target, turn1 , Flags::Vertical );
|
||||
target = turn1;
|
||||
}
|
||||
AutoSegment::create( source, target, Flags::Horizontal );
|
||||
} else {
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
turn2 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( source, turn1 , Flags::Horizontal );
|
||||
AutoSegment::create( turn1 , turn2 , Flags::Vertical );
|
||||
AutoSegment::create( turn2 , target, Flags::Horizontal );
|
||||
}
|
||||
}
|
||||
|
||||
if (rpM2) {
|
||||
doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact );
|
||||
doRp_AutoContacts( gcell1, rpM2 , target, turn1, DoSourceContact );
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM2->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( source, turn1 , Flags::Horizontal );
|
||||
AutoSegment::create( turn1 , target, Flags::Vertical );
|
||||
}
|
||||
|
||||
if (rpPin) {
|
||||
Pin* pin = dynamic_cast<Pin*>( rpPin->getOccurrence().getEntity() );
|
||||
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||
|
||||
if ( (pinDir == Pin::AccessDirection::NORTH)
|
||||
or (pinDir == Pin::AccessDirection::SOUTH) ) {
|
||||
doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact );
|
||||
target = doRp_AccessNorthPin( gcell1, rpPin );
|
||||
turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( source, turn1 , Flags::Horizontal );
|
||||
AutoSegment::create( turn1 , target, Flags::Vertical );
|
||||
} else {
|
||||
RoutingPad* closest = NULL;
|
||||
|
||||
if (pinDir == Pin::AccessDirection::EAST) closest = rpM1s.back();
|
||||
else closest = rpM1s.front();
|
||||
|
||||
doRp_AutoContacts( gcell1, closest, source, turn1, DoSourceContact );
|
||||
target = doRp_AccessEastWestPin( gcell1, rpPin );
|
||||
AutoSegment::create( source, target , Flags::Horizontal );
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
string NetBuilderHV::getTypeName () const
|
||||
{ return "NetBuilderHV"; }
|
||||
|
||||
|
|
|
@ -318,7 +318,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
|
|
|
@ -521,12 +521,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_2G ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_2G()" << endl;
|
||||
return _do_xG();
|
||||
}
|
||||
|
||||
bool NetBuilderVH::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
@ -577,7 +571,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace Anabatic {
|
|||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::DeepNet;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::NetRoutingExtension;
|
||||
|
@ -86,30 +85,16 @@ namespace Anabatic {
|
|||
vector<Segment*> segments;
|
||||
vector<Contact*> contacts;
|
||||
|
||||
bool isManualGlobalRouted = false;
|
||||
bool isManualDetailRouted = false;
|
||||
bool isFixed = false;
|
||||
size_t rpCount = 0;
|
||||
bool isPreRouted = false;
|
||||
bool isFixed = false;
|
||||
size_t rpCount = 0;
|
||||
|
||||
for( Component* component : net->getComponents() ) {
|
||||
if (dynamic_cast<Pin *>(component)) continue;
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
if (dynamic_cast<Pin*>(component)) continue;
|
||||
|
||||
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
|
||||
if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage))
|
||||
continue;
|
||||
|
||||
if ( not Session::isGaugeLayer(component->getLayer())
|
||||
and not Session::isGLayer (component->getLayer())) {
|
||||
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( component->getLayer() );
|
||||
if (basicLayer and (basicLayer->getMaterial() == BasicLayer::Material::cut))
|
||||
continue;
|
||||
throw Error( "AnabaticEngine::setupPreRouted(): A component of \"%s\" has a routing gauge umanaged layer.\n"
|
||||
" (%s)"
|
||||
, getString(net->getName()).c_str()
|
||||
, getString(component).c_str()
|
||||
);
|
||||
}
|
||||
continue;
|
||||
|
||||
Horizontal* horizontal = dynamic_cast<Horizontal*>(component);
|
||||
if (horizontal) {
|
||||
|
@ -117,42 +102,30 @@ namespace Anabatic {
|
|||
and not ab.contains(horizontal->getTargetPosition()) ) continue;
|
||||
|
||||
segments.push_back( horizontal );
|
||||
if (Session::isGLayer(component->getLayer())) {
|
||||
isManualGlobalRouted = true;
|
||||
} else {
|
||||
isManualDetailRouted = true;
|
||||
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
|
||||
isFixed = true;
|
||||
}
|
||||
isPreRouted = true;
|
||||
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
|
||||
isFixed = true;
|
||||
} else {
|
||||
Vertical* vertical = dynamic_cast<Vertical*>(component);
|
||||
if (vertical) {
|
||||
if ( not ab.contains(vertical->getSourcePosition())
|
||||
and not ab.contains(vertical->getTargetPosition()) ) continue;
|
||||
|
||||
if (Session::isGLayer(component->getLayer())) {
|
||||
isManualGlobalRouted = true;
|
||||
} else {
|
||||
isManualDetailRouted = true;
|
||||
segments.push_back( vertical );
|
||||
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
|
||||
isFixed = true;
|
||||
}
|
||||
isPreRouted = true;
|
||||
segments.push_back( vertical );
|
||||
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
|
||||
isFixed = true;
|
||||
} else {
|
||||
Contact* contact = dynamic_cast<Contact*>(component);
|
||||
if (contact) {
|
||||
if (not ab.contains(contact->getCenter())) continue;
|
||||
|
||||
if (Session::isGLayer(component->getLayer())) {
|
||||
isManualGlobalRouted = true;
|
||||
} else {
|
||||
isManualGlobalRouted = true;
|
||||
contacts.push_back( contact );
|
||||
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
|
||||
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
|
||||
or (contact->getLayer () == Session::getContactLayer(0)) )
|
||||
isFixed = true;
|
||||
}
|
||||
isPreRouted = true;
|
||||
contacts.push_back( contact );
|
||||
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
|
||||
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
|
||||
or (contact->getLayer () == Session::getContactLayer(0)) )
|
||||
isFixed = true;
|
||||
} else {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
|
||||
if (rp) {
|
||||
|
@ -169,10 +142,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
if ( (not isFixed)
|
||||
and (not isManualGlobalRouted)
|
||||
and (not isManualDetailRouted)
|
||||
and net->isDeepNet()) {
|
||||
if ((not isFixed and not isPreRouted) and net->isDeepNet()) {
|
||||
Net* rootNet = dynamic_cast<Net*>(
|
||||
dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
|
||||
for( Component* component : rootNet->getComponents() ) {
|
||||
|
@ -182,34 +152,29 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
if (isFixed or isManualDetailRouted or isManualGlobalRouted or (rpCount < 2)) {
|
||||
if (isFixed or isPreRouted or (rpCount < 2)) {
|
||||
NetData* ndata = getNetData( net, Flags::Create );
|
||||
NetRoutingState* state = ndata->getNetRoutingState();
|
||||
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
|
||||
if (isManualGlobalRouted) {
|
||||
state->setFlags( NetRoutingState::ManualGlobalRoute );
|
||||
ndata->setGlobalFixed( true );
|
||||
}
|
||||
if (isManualDetailRouted)
|
||||
state->setFlags( NetRoutingState::ManualDetailRoute );
|
||||
state->setFlags ( NetRoutingState::ManualGlobalRoute );
|
||||
ndata->setGlobalRouted( true );
|
||||
if (rpCount < 2)
|
||||
state->setFlags( NetRoutingState::Unconnected );
|
||||
state->setFlags ( NetRoutingState::Unconnected );
|
||||
|
||||
if (isFixed) {
|
||||
if (rpCount > 1)
|
||||
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
|
||||
state->unsetFlags( NetRoutingState::ManualGlobalRoute|NetRoutingState::ManualDetailRoute );
|
||||
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
|
||||
state->setFlags ( NetRoutingState::Fixed );
|
||||
} else if (isManualGlobalRouted) {
|
||||
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
|
||||
} else if (isManualDetailRouted) {
|
||||
} else {
|
||||
if (rpCount > 1) {
|
||||
++toBeRouteds;
|
||||
cmess2 << " - <" << net->getName() << "> is manually detail routed." << endl;
|
||||
for ( auto contact : contacts ) {
|
||||
AutoContact::createFrom( contact );
|
||||
|
||||
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
|
||||
for ( auto icontact : contacts ) {
|
||||
AutoContact::createFrom( icontact );
|
||||
}
|
||||
|
||||
for ( auto segment : segments ) {
|
||||
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() ));
|
||||
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( segment->getTarget() ));
|
||||
|
|
|
@ -82,12 +82,7 @@ namespace Anabatic {
|
|||
, _segmentRevalidateds()
|
||||
, _netInvalidateds ()
|
||||
, _netRevalidateds ()
|
||||
{
|
||||
_autoContacts .reserve( 1024 );
|
||||
_doglegs .reserve( 1024 );
|
||||
_segmentInvalidateds.reserve( 1024 );
|
||||
_segmentRevalidateds.reserve( 1024 );
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
void Session::_postCreate ()
|
||||
|
@ -224,9 +219,7 @@ namespace Anabatic {
|
|||
}
|
||||
_canonize ();
|
||||
|
||||
AutoSegment* segment = NULL;
|
||||
for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) {
|
||||
segment = _segmentInvalidateds[i];
|
||||
for ( AutoSegment* segment : _segmentInvalidateds ) {
|
||||
if (segment->isCanonical()) {
|
||||
if (segment->isUnsetAxis()) segment->toOptimalAxis();
|
||||
else segment->toConstraintAxis();
|
||||
|
@ -259,8 +252,6 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl;
|
||||
|
||||
_segmentRevalidateds.clear();
|
||||
std::sort( _segmentInvalidateds.begin(), _segmentInvalidateds.end()
|
||||
, AutoSegment::CompareByRevalidate() );
|
||||
for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) {
|
||||
_segmentInvalidateds[i]->revalidate();
|
||||
if ( not _destroyedSegments.empty()
|
||||
|
@ -362,31 +353,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
DbU::Unit Session::_getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode )
|
||||
{
|
||||
Box ab = _anabatic->getCell()->getAbutmentBox();
|
||||
|
||||
RoutingLayerGauge* lg = _routingGauge->getLayerGauge( layer );
|
||||
if (not lg) return axis;
|
||||
|
||||
DbU::Unit minAxis = 0;
|
||||
DbU::Unit maxAxis = 0;
|
||||
if (lg->getDirection() == Constant::Horizontal) {
|
||||
minAxis = ab.getYMin();
|
||||
maxAxis = ab.getYMax();
|
||||
} else {
|
||||
minAxis = ab.getXMin();
|
||||
maxAxis = ab.getXMax();
|
||||
}
|
||||
DbU::Unit trackAxis = lg->getTrackPosition( minAxis
|
||||
, lg->getTrackIndex( minAxis
|
||||
, maxAxis
|
||||
, axis
|
||||
, mode ) );
|
||||
return trackAxis;
|
||||
}
|
||||
|
||||
|
||||
Point Session::_getNearestGridPoint ( Point p, Box constraint )
|
||||
{
|
||||
Box ab = _anabatic->getCell()->getAbutmentBox();
|
||||
|
|
|
@ -14,16 +14,20 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_ANABATIC_ENGINE_H
|
||||
#define ANABATIC_ANABATIC_ENGINE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "hurricane/NetRoutingProperty.h"
|
||||
namespace Hurricane {
|
||||
class Instance;
|
||||
class CellViewer;
|
||||
}
|
||||
|
||||
#include "crlcore/ToolEngine.h"
|
||||
#include "anabatic/Configuration.h"
|
||||
#include "anabatic/Matrix.h"
|
||||
|
@ -100,10 +104,9 @@ namespace Anabatic {
|
|||
|
||||
class NetData {
|
||||
public:
|
||||
NetData ( Net*, AnabaticEngine* );
|
||||
NetData ( Net* );
|
||||
inline bool isGlobalEstimated () const;
|
||||
inline bool isGlobalRouted () const;
|
||||
inline bool isGlobalFixed () const;
|
||||
inline bool isMixedPreRoute () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isExcluded () const;
|
||||
|
@ -112,13 +115,11 @@ namespace Anabatic {
|
|||
inline const Box& getSearchArea () const;
|
||||
inline DbU::Unit getHalfPerimeter () const;
|
||||
inline size_t getRpCount () const;
|
||||
inline size_t getDiodeRpCount () const;
|
||||
inline DbU::Unit getSparsity () const;
|
||||
inline void setNetRoutingState ( NetRoutingState* );
|
||||
inline void setSearchArea ( Box );
|
||||
inline void setGlobalEstimated ( bool );
|
||||
inline void setGlobalRouted ( bool );
|
||||
inline void setGlobalFixed ( bool );
|
||||
inline void setExcluded ( bool );
|
||||
inline void setRpCount ( size_t );
|
||||
private:
|
||||
|
@ -130,7 +131,6 @@ namespace Anabatic {
|
|||
NetRoutingState* _state;
|
||||
Box _searchArea;
|
||||
size_t _rpCount;
|
||||
size_t _diodeCount;
|
||||
DbU::Unit _sparsity;
|
||||
Flags _flags;
|
||||
};
|
||||
|
@ -138,7 +138,6 @@ namespace Anabatic {
|
|||
|
||||
inline bool NetData::isGlobalEstimated () const { return _flags & Flags::GlobalEstimated; }
|
||||
inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; }
|
||||
inline bool NetData::isGlobalFixed () const { return _flags & Flags::GlobalFixed; }
|
||||
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
|
||||
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : false; }
|
||||
inline bool NetData::isExcluded () const { return _flags & Flags::ExcludeRoute; }
|
||||
|
@ -147,12 +146,10 @@ namespace Anabatic {
|
|||
inline const Box& NetData::getSearchArea () const { return _searchArea; }
|
||||
inline DbU::Unit NetData::getHalfPerimeter () const { return (_searchArea.isEmpty()) ? 0.0 : (_searchArea.getWidth()+_searchArea.getHeight()); }
|
||||
inline size_t NetData::getRpCount () const { return _rpCount; }
|
||||
inline size_t NetData::getDiodeRpCount () const { return _diodeCount; }
|
||||
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
|
||||
inline DbU::Unit NetData::getSparsity () const { return _sparsity; }
|
||||
inline void NetData::setGlobalEstimated ( bool state ) { _flags.set(Flags::GlobalEstimated,state); }
|
||||
inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted ,state); }
|
||||
inline void NetData::setGlobalFixed ( bool state ) { _flags.set(Flags::GlobalFixed ,state); }
|
||||
inline void NetData::setExcluded ( bool state ) { _flags.set(Flags::ExcludeRoute ,state); }
|
||||
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
|
||||
|
||||
|
@ -202,7 +199,6 @@ namespace Anabatic {
|
|||
static const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual Configuration* getConfiguration ();
|
||||
virtual const Configuration* getConfiguration () const;
|
||||
inline uint64_t getDensityMode () const;
|
||||
inline CellViewer* getViewer () const;
|
||||
inline void setViewer ( CellViewer* );
|
||||
|
@ -230,7 +226,6 @@ namespace Anabatic {
|
|||
void exclude ( const Name& netName );
|
||||
void exclude ( Net* );
|
||||
void updateMatrix ();
|
||||
bool checkPlacement () const;
|
||||
// Dijkstra related functions.
|
||||
inline int getStamp () const;
|
||||
inline int incStamp ();
|
||||
|
@ -248,13 +243,10 @@ namespace Anabatic {
|
|||
inline bool doDestroyBaseContact () const;
|
||||
inline bool doDestroyBaseSegment () const;
|
||||
inline bool doDestroyTool () const;
|
||||
inline DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
inline DbU::Unit getGlobalThreshold () const;
|
||||
inline float getSaturateRatio () const;
|
||||
inline size_t getSaturateRp () const;
|
||||
inline DbU::Unit getExtensionCap () const;
|
||||
inline Cell* getDiodeCell () const;
|
||||
inline Net* getBlockageNet () const;
|
||||
inline const ChipTools& getChipTools () const;
|
||||
inline const vector<NetData*>& getNetOrdering () const;
|
||||
|
@ -267,8 +259,6 @@ namespace Anabatic {
|
|||
inline void setBlockageNet ( Net* );
|
||||
void chipPrep ();
|
||||
void computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat );
|
||||
void antennaProtect ( Net*, uint32_t& failed, uint32_t& total );
|
||||
void antennaProtect ();
|
||||
void setupSpecialNets ();
|
||||
size_t setupPreRouteds ();
|
||||
void loadGlobalRouting ( uint32_t method );
|
||||
|
@ -278,7 +268,6 @@ namespace Anabatic {
|
|||
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds );
|
||||
void layerAssign ( uint32_t method );
|
||||
void finalizeLayout ();
|
||||
void exportExternalNets ();
|
||||
inline const AutoContactLut& _getAutoContactLut () const;
|
||||
inline const AutoSegmentLut& _getAutoSegmentLut () const;
|
||||
void _link ( AutoContact* );
|
||||
|
@ -347,7 +336,6 @@ namespace Anabatic {
|
|||
AutoContactLut _autoContactLut;
|
||||
EdgeCapacityLut _edgeCapacitiesLut;
|
||||
Net* _blockageNet;
|
||||
Cell* _diodeCell;
|
||||
};
|
||||
|
||||
|
||||
|
@ -377,14 +365,11 @@ namespace Anabatic {
|
|||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
||||
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return getConfiguration()->getAntennaDiodeMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
|
||||
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
|
||||
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
|
||||
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
|
||||
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
|
||||
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; }
|
||||
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
|
||||
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
|
||||
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
|
||||
|
@ -432,3 +417,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine);
|
||||
|
||||
#endif // ANABATIC_ANABATIC_ENGINE_H
|
||||
|
|
|
@ -123,7 +123,6 @@ namespace Anabatic {
|
|||
inline bool isUserNativeConstraints () const;
|
||||
inline bool isHDogleg () const;
|
||||
inline bool isVDogleg () const;
|
||||
virtual bool isOnPin () const;
|
||||
inline bool hasBadTopology () const;
|
||||
bool canDestroy ( Flags flags=Flags::NoFlags ) const;
|
||||
bool canMoveUp ( const AutoSegment* moved ) const;
|
||||
|
|
|
@ -60,7 +60,6 @@ namespace Anabatic {
|
|||
virtual void _invalidate ( Flags flags );
|
||||
public:
|
||||
bool isEndPoint () const;
|
||||
virtual bool isOnPin () const;
|
||||
virtual Box getNativeConstraintBox () const;
|
||||
RoutingPad* getRoutingPad () const;
|
||||
inline AutoSegment* getSegment () const;
|
||||
|
|
|
@ -107,7 +107,6 @@ namespace Anabatic {
|
|||
static const uint64_t SegShortNet = (1L<<35);
|
||||
static const uint64_t SegUnbreakable = (1L<<36);
|
||||
static const uint64_t SegNonPref = (1L<<37);
|
||||
static const uint64_t SegAtMinArea = (1L<<38);
|
||||
// Masks.
|
||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||
|
@ -142,7 +141,6 @@ namespace Anabatic {
|
|||
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||
inline static DbU::Unit getMinimalLength ( size_t depth );
|
||||
static AutoSegment* create ( AutoContact* source
|
||||
, AutoContact* target
|
||||
, Segment* hurricaneSegment
|
||||
|
@ -173,8 +171,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit getWidth () const;
|
||||
inline DbU::Unit getContactWidth () const;
|
||||
inline DbU::Unit getLength () const;
|
||||
inline DbU::Unit getSpanLength () const;
|
||||
inline DbU::Unit getAnchoredLength () const;
|
||||
inline DbU::Unit getSourcePosition () const;
|
||||
inline DbU::Unit getTargetPosition () const;
|
||||
inline DbU::Unit getSourceX () const;
|
||||
|
@ -202,7 +198,6 @@ namespace Anabatic {
|
|||
inline bool isUnbreakable () const;
|
||||
inline bool isNonPref () const;
|
||||
inline bool isDrag () const;
|
||||
inline bool isAtMinArea () const;
|
||||
inline bool isNotSourceAligned () const;
|
||||
inline bool isNotTargetAligned () const;
|
||||
inline bool isNotAligned () const;
|
||||
|
@ -210,12 +205,10 @@ namespace Anabatic {
|
|||
inline bool isSourceTerminal () const;
|
||||
inline bool isTargetTerminal () const;
|
||||
inline bool isLayerChange () const;
|
||||
inline bool isStackedStrap () const;
|
||||
inline bool isSpinTop () const;
|
||||
inline bool isSpinBottom () const;
|
||||
inline bool isSpinTopOrBottom () const;
|
||||
inline bool isReduced () const;
|
||||
bool isUnderMinLength () const;
|
||||
inline bool isStrap () const;
|
||||
inline bool isDogleg () const;
|
||||
inline bool isUnbound () const;
|
||||
|
@ -226,14 +219,13 @@ namespace Anabatic {
|
|||
inline bool isUnsetAxis () const;
|
||||
inline bool isSlackened () const;
|
||||
inline bool isUserDefined () const;
|
||||
bool isMiddleStack () const;
|
||||
bool isReduceCandidate () const;
|
||||
bool isUTurn () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isWide () const;
|
||||
inline bool isShortNet () const;
|
||||
virtual bool _canSlacken () const = 0;
|
||||
bool canReduce ( Flags flags=Flags::WithPerpands ) const;
|
||||
bool canReduce () const;
|
||||
bool mustRaise () const;
|
||||
Flags canDogleg ( Interval );
|
||||
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
||||
|
@ -290,8 +282,6 @@ namespace Anabatic {
|
|||
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
||||
inline AutoSegment* getCanonical ( Interval& i );
|
||||
float getMaxUnderDensity ( Flags flags );
|
||||
inline uint32_t getReduceds () const;
|
||||
uint32_t getNonReduceds ( Flags flags=Flags::WithPerpands ) const;
|
||||
// Modifiers.
|
||||
inline void unsetFlags ( uint64_t );
|
||||
inline void setFlags ( uint64_t );
|
||||
|
@ -335,11 +325,8 @@ namespace Anabatic {
|
|||
bool moveUp ( Flags flags=Flags::NoFlags );
|
||||
bool moveDown ( Flags flags=Flags::NoFlags );
|
||||
bool reduceDoglegLayer ();
|
||||
bool bloatStackedStrap ();
|
||||
bool reduce ( Flags flags=Flags::WithPerpands );
|
||||
bool reduce ();
|
||||
bool raise ();
|
||||
bool expandToMinLength ( Interval );
|
||||
bool unexpandToMinLength ();
|
||||
// Canonical Modifiers.
|
||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||
|
@ -383,7 +370,7 @@ namespace Anabatic {
|
|||
static bool _analogMode;
|
||||
static bool _shortNetMode;
|
||||
static bool _initialized;
|
||||
static vector< array<DbU::Unit*,4> > _extensionCaps;
|
||||
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||
// Internal: Attributes.
|
||||
const unsigned long _id;
|
||||
GCell* _gcell;
|
||||
|
@ -433,13 +420,6 @@ namespace Anabatic {
|
|||
struct CompareBySourceU : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByRevalidate : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
struct CompareByReduceds : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||
|
@ -484,7 +464,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getMinimalLength ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][3]) : 0; }
|
||||
inline unsigned long AutoSegment::getId () const { return _id; }
|
||||
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
||||
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
||||
|
@ -522,7 +501,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
|
||||
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
|
||||
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
|
||||
inline uint32_t AutoSegment::getReduceds () const { return _reduceds; }
|
||||
|
||||
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
||||
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
||||
|
@ -542,7 +520,6 @@ namespace Anabatic {
|
|||
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
||||
inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); }
|
||||
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
||||
inline bool AutoSegment::isAtMinArea () const { return _flags & SegAtMinArea; }
|
||||
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
||||
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
||||
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
||||
|
@ -581,7 +558,7 @@ namespace Anabatic {
|
|||
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
||||
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||
inline DbU::Unit AutoSegment::getAnchoredLength () const { return std::abs(getTargetU() - getSourceU()); }
|
||||
|
||||
|
||||
inline void AutoSegment::setLayer ( size_t depth )
|
||||
{
|
||||
|
@ -593,13 +570,10 @@ namespace Anabatic {
|
|||
_flags|=SegInvalidatedLayer;
|
||||
}
|
||||
|
||||
|
||||
inline DbU::Unit AutoSegment::getContactWidth () const
|
||||
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||
|
||||
inline DbU::Unit AutoSegment::getSpanLength () const
|
||||
{ return getAnchoredLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||
+ getExtensionCap( Flags::Target|Flags::LayerCapOnly|Flags::NoMinLength );
|
||||
}
|
||||
|
||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||
{
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_CHIP_TOOLS_H
|
||||
#define ANABATIC_CHIP_TOOLS_H
|
||||
|
||||
#include <string>
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Torus.h"
|
||||
|
@ -111,4 +113,6 @@ namespace Anabatic {
|
|||
|
||||
} // Anabatic namespace.
|
||||
|
||||
INSPECTOR_PR_SUPPORT(Anabatic::ChipTools);
|
||||
INSPECTOR_PV_SUPPORT(Anabatic::ChipTools);
|
||||
|
||||
#endif // ANABATIC_CHIP_TOOLS_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_CONFIGURATION_H
|
||||
#define ANABATIC_CONFIGURATION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -62,7 +64,6 @@ namespace Anabatic {
|
|||
virtual ~Configuration ();
|
||||
virtual Configuration* clone () const;
|
||||
// Methods.
|
||||
inline bool isGLayer ( const Layer* ) const;
|
||||
bool isGMetal ( const Layer* ) const;
|
||||
bool isGContact ( const Layer* ) const;
|
||||
bool isTwoMetals () const;
|
||||
|
@ -78,13 +79,11 @@ namespace Anabatic {
|
|||
inline size_t getDVerticalDepth () const;
|
||||
inline const Layer* getDVerticalLayer () const;
|
||||
inline DbU::Unit getDVerticalWidth () const;
|
||||
inline DbU::Unit getDPVerticalWidth () const;
|
||||
inline DbU::Unit getDVerticalPitch () const;
|
||||
inline DbU::Unit getDVerticalOffset () const;
|
||||
inline size_t getDHorizontalDepth () const;
|
||||
inline const Layer* getDHorizontalLayer () const;
|
||||
inline DbU::Unit getDHorizontalWidth () const;
|
||||
inline DbU::Unit getDPHorizontalWidth () const;
|
||||
inline DbU::Unit getDHorizontalPitch () const;
|
||||
inline DbU::Unit getDHorizontalOffset () const;
|
||||
inline size_t getDContactDepth () const;
|
||||
|
@ -104,20 +103,15 @@ namespace Anabatic {
|
|||
DbU::Unit getPitch ( size_t depth, Flags flags ) const;
|
||||
DbU::Unit getOffset ( size_t depth ) const;
|
||||
DbU::Unit getWireWidth ( size_t depth ) const;
|
||||
DbU::Unit getPWireWidth ( size_t depth ) const;
|
||||
DbU::Unit getExtensionCap ( size_t depth ) const;
|
||||
Flags getDirection ( size_t depth ) const;
|
||||
DbU::Unit getPitch ( const Layer*, Flags flags ) const;
|
||||
DbU::Unit getOffset ( const Layer* ) const;
|
||||
DbU::Unit getWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getPWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getExtensionCap ( const Layer* ) const;
|
||||
Flags getDirection ( const Layer* ) const;
|
||||
float getSaturateRatio () const;
|
||||
size_t getSaturateRp () const;
|
||||
inline std::string getDiodeName () const;
|
||||
inline DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
DbU::Unit getGlobalThreshold () const;
|
||||
void setAllowedDepth ( size_t );
|
||||
void setSaturateRatio ( float );
|
||||
|
@ -160,16 +154,12 @@ namespace Anabatic {
|
|||
float _edgeHInc;
|
||||
float _edgeHScaling;
|
||||
int _globalIterations;
|
||||
std::string _diodeName;
|
||||
DbU::Unit _antennaGateMaxWL;
|
||||
DbU::Unit _antennaDiodeMaxWL;
|
||||
private:
|
||||
Configuration& operator= ( const Configuration& ) = delete;
|
||||
void _setTopRoutingLayer ( Name name );
|
||||
};
|
||||
|
||||
|
||||
inline bool Configuration::isGLayer ( const Layer* layer ) const { return isGMetal(layer) or isGContact(layer); }
|
||||
inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; }
|
||||
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
|
||||
inline DbU::Unit Configuration::getGHorizontalPitch () const { return getPitch( getGHorizontalDepth(), Flags::NoFlags ); }
|
||||
|
@ -177,25 +167,22 @@ namespace Anabatic {
|
|||
inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; }
|
||||
inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDPVerticalWidth () const { return getPWireWidth ( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); }
|
||||
inline DbU::Unit Configuration::getDVerticalOffset () const { return getOffset ( getDVerticalDepth() ); }
|
||||
inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; }
|
||||
inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDPHorizontalWidth () const { return getPWireWidth ( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalOffset () const { return getOffset ( getDHorizontalDepth() ); }
|
||||
inline size_t Configuration::getDContactDepth () const { return _ddepthc; }
|
||||
inline const Layer* Configuration::getDContactLayer () const { return getContactLayer( getDContactDepth() ); }
|
||||
inline DbU::Unit Configuration::getDContactWidth () const { return getWireWidth ( getDContactDepth() ); }
|
||||
inline DbU::Unit Configuration::getDContactPitch () const { return getPitch ( getDContactDepth(), Flags::NoFlags ); }
|
||||
inline std::string Configuration::getDiodeName () const { return _diodeName; }
|
||||
inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; }
|
||||
inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::Configuration);
|
||||
|
||||
#endif // ANABATIC_CONFIGURATION_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_CONSTANTS_H
|
||||
#define ANABATIC_CONSTANTS_H
|
||||
|
||||
#include "hurricane/Flags.h"
|
||||
|
||||
namespace Anabatic {
|
||||
|
@ -52,11 +54,9 @@ namespace Anabatic {
|
|||
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
|
||||
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
||||
// Flags for NetDatas objects states only.
|
||||
static const BaseFlags GlobalFixed ; // = (1 << 5);
|
||||
static const BaseFlags GlobalRouted ; // = (1 << 5);
|
||||
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
||||
static const BaseFlags GlobalRouted ; // = (1 << 7);
|
||||
static const BaseFlags DetailRouted ; // = (1 << 8);
|
||||
static const BaseFlags ExcludeRoute ; // = (1 << 9);
|
||||
static const BaseFlags ExcludeRoute ; // = (1 << 7);
|
||||
// Masks.
|
||||
static const BaseFlags WestSide ; // = Horizontal|Target;
|
||||
static const BaseFlags EastSide ; // = Horizontal|Source;
|
||||
|
@ -102,10 +102,6 @@ namespace Anabatic {
|
|||
static const BaseFlags NorthPath ;
|
||||
static const BaseFlags UseNonPref ;
|
||||
static const BaseFlags Force ;
|
||||
static const BaseFlags LayerCapOnly ;
|
||||
static const BaseFlags NoMinLength ;
|
||||
static const BaseFlags NoSegExt ;
|
||||
static const BaseFlags NullLength ;
|
||||
public:
|
||||
inline Flags ( uint64_t flags = NoFlags );
|
||||
inline Flags ( const Hurricane::BaseFlags& );
|
||||
|
@ -152,4 +148,6 @@ namespace Anabatic {
|
|||
} // Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_PR_SUPPORT(Anabatic::Flags);
|
||||
INSPECTOR_PV_SUPPORT(Anabatic::Flags)
|
||||
|
||||
#endif // ANABATIC_CONSTANTS_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_DIJKSTRA_H
|
||||
#define ANABATIC_DIJKSTRA_H
|
||||
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
#include "hurricane/Observer.h"
|
||||
|
@ -187,7 +189,6 @@ namespace Anabatic {
|
|||
, iHorizontal = (1<<7)
|
||||
, iVertical = (1<<8)
|
||||
, iSet = (1<<9)
|
||||
, Driver = (1<<10)
|
||||
};
|
||||
public:
|
||||
static DbU::Unit unreached;
|
||||
|
@ -199,7 +200,6 @@ namespace Anabatic {
|
|||
inline Vertex ( GCell* );
|
||||
//inline Vertex ( size_t id );
|
||||
inline ~Vertex ();
|
||||
inline bool isDriver () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool hasDoneAllRps () const;
|
||||
inline Contact* hasGContact ( Net* ) const;
|
||||
|
@ -220,7 +220,6 @@ namespace Anabatic {
|
|||
Edge* getFrom () const;
|
||||
inline Vertex* getPredecessor () const;
|
||||
inline Vertex* getNeighbor ( Edge* ) const;
|
||||
inline void setDriver ( bool state );
|
||||
inline void setDistance ( DbU::Unit );
|
||||
inline void setStamp ( int );
|
||||
inline void setConnexId ( int );
|
||||
|
@ -334,7 +333,6 @@ namespace Anabatic {
|
|||
|
||||
inline Vertex* Vertex::lookup ( GCell* gcell ) { return gcell->getObserver<Vertex>(GCell::Observable::Vertex); }
|
||||
inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); }
|
||||
inline bool Vertex::isDriver () const { return _flags & Driver; }
|
||||
inline bool Vertex::isAnalog () const { return _gcell->isAnalog(); }
|
||||
inline Box Vertex::getBoundingBox () const { return _gcell->getBoundingBox(); }
|
||||
inline Edges Vertex::getEdges ( Flags sides ) const { return _gcell->getEdges(sides); }
|
||||
|
@ -371,12 +369,6 @@ namespace Anabatic {
|
|||
return (gcell) ? gcell->getObserver<Vertex>(GCell::Observable::Vertex) : NULL;
|
||||
}
|
||||
|
||||
inline void Vertex::setDriver ( bool state )
|
||||
{
|
||||
if (state) _flags |= Driver;
|
||||
else _flags &= ~Driver;
|
||||
}
|
||||
|
||||
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
||||
|
@ -522,13 +514,11 @@ namespace Anabatic {
|
|||
inline bool isSourceVertex ( Vertex* ) const;
|
||||
inline Net* getNet () const;
|
||||
inline bool isTargetVertex ( Vertex* ) const;
|
||||
DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getSearchAreaHalo () const;
|
||||
template<typename DistanceT>
|
||||
inline DistanceT* setDistance ( DistanceT );
|
||||
inline void setSearchAreaHalo ( DbU::Unit );
|
||||
void load ( Net* net );
|
||||
void loadFixedGlobal ( Net* net );
|
||||
void run ( Mode mode=Mode::Standart );
|
||||
inline const VertexSet& getSources () const;
|
||||
private:
|
||||
|
@ -603,4 +593,6 @@ namespace Anabatic {
|
|||
|
||||
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
|
||||
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
|
||||
INSPECTOR_PR_SUPPORT(Anabatic::Dijkstra::Mode);
|
||||
INSPECTOR_PV_SUPPORT(Anabatic::Dijkstra::Mode);
|
||||
|
||||
#endif // ANABATIC_DIJKSTRA_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_EDGE_H
|
||||
#define ANABATIC_EDGE_H
|
||||
|
||||
#include <string>
|
||||
#include "hurricane/Name.h"
|
||||
#include "hurricane/Interval.h"
|
||||
|
@ -166,3 +168,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::Edge);
|
||||
|
||||
#endif // ANABATIC_EDGE_H
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_GCELL_H
|
||||
#define ANABATIC_GCELL_H
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
|
@ -114,22 +115,14 @@ namespace Anabatic {
|
|||
public:
|
||||
class Key {
|
||||
public:
|
||||
inline Key ( const GCell*, size_t depth );
|
||||
inline ~Key ();
|
||||
inline float getDensity () const;
|
||||
inline const GCell* getGCell () const;
|
||||
inline bool isActive () const;
|
||||
inline bool isSaturated () const;
|
||||
inline void update ( size_t depth );
|
||||
friend bool operator< ( const Key&, const Key& );
|
||||
public:
|
||||
class Compare {
|
||||
public:
|
||||
inline bool operator() ( const Key*, const Key* );
|
||||
};
|
||||
inline Key ( GCell*, size_t depth );
|
||||
inline float getDensity () const;
|
||||
inline GCell* getGCell () const;
|
||||
inline void update ( size_t depth );
|
||||
friend bool operator< ( const Key&, const Key& );
|
||||
private:
|
||||
const GCell* _gcell;
|
||||
float _density;
|
||||
GCell* _gcell;
|
||||
float _density;
|
||||
};
|
||||
public:
|
||||
static uint32_t getDisplayMode ();
|
||||
|
@ -163,7 +156,6 @@ namespace Anabatic {
|
|||
bool isEast ( GCell* ) const;
|
||||
bool isNorth ( GCell* ) const;
|
||||
bool isSouth ( GCell* ) const;
|
||||
bool hasNet ( const Net* ) const;
|
||||
Contact* hasGContact ( const Contact* ) const;
|
||||
Contact* hasGContact ( const Net* ) const;
|
||||
bool isHorizontalPlane ( size_t depth ) const;
|
||||
|
@ -215,8 +207,7 @@ namespace Anabatic {
|
|||
bool doGrid ();
|
||||
Contact* getGContact ( Net* );
|
||||
inline const vector<Contact*>& getGContacts () const;
|
||||
Segment* hasGoThrough ( Net* ) const;
|
||||
Contact* breakGoThrough ( Net* );
|
||||
Contact* breakGoThrough ( Net* net );
|
||||
bool unrefContact ( Contact* );
|
||||
void setSouthWestCorner ( DbU::Unit x, DbU::Unit y );
|
||||
void cleanupGlobal ();
|
||||
|
@ -251,9 +242,6 @@ namespace Anabatic {
|
|||
inline AutoSegments getStopSegments ( Flags direction );
|
||||
size_t getRoutingPads ( set<RoutingPad*>& );
|
||||
inline const Key& getKey () const;
|
||||
inline Key* cloneKey ( size_t depth ) const;
|
||||
inline Key* getLastClonedKey () const;
|
||||
inline void clearClonedKey () const;
|
||||
size_t checkDensity () const;
|
||||
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
|
||||
void setType ( Flags );
|
||||
|
@ -342,71 +330,67 @@ namespace Anabatic {
|
|||
float* _fragmentations;
|
||||
float* _globalsCount;
|
||||
Key _key;
|
||||
mutable Key* _lastClonedKey;
|
||||
};
|
||||
|
||||
|
||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
|
||||
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
|
||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
|
||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
||||
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
||||
inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; }
|
||||
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
||||
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
||||
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
||||
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
|
||||
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
|
||||
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
|
||||
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; }
|
||||
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; }
|
||||
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
|
||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||
inline Interval GCell::getHSide ( int shrink ) const { return getSide(Flags::Horizontal,shrink); }
|
||||
inline Interval GCell::getVSide ( int shrink ) const { return getSide(Flags::Vertical ,shrink); }
|
||||
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
|
||||
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
||||
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
|
||||
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
||||
|
||||
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
|
||||
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
|
||||
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
|
||||
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
|
||||
|
||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||
inline size_t GCell::getDepth () const { return _depth; }
|
||||
inline int GCell::getRpCount () const { return _rpCount; }
|
||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||
|
||||
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
||||
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
|
||||
|
||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
||||
inline GCell::Key* GCell::cloneKey ( size_t depth ) const { _lastClonedKey = new Key(this,depth); return _lastClonedKey; }
|
||||
inline void GCell::clearClonedKey () const { _lastClonedKey=NULL; }
|
||||
inline GCell::Key* GCell::getLastClonedKey () const { return _lastClonedKey; }
|
||||
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
inline Flags& GCell::flags () { return _flags; }
|
||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
|
||||
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
|
||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
|
||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
||||
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
||||
inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; }
|
||||
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
||||
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
||||
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
||||
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
|
||||
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
|
||||
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
|
||||
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; }
|
||||
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; }
|
||||
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
|
||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||
inline Interval GCell::getHSide ( int shrink ) const { return getSide(Flags::Horizontal,shrink); }
|
||||
inline Interval GCell::getVSide ( int shrink ) const { return getSide(Flags::Vertical ,shrink); }
|
||||
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
|
||||
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
||||
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
|
||||
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
||||
|
||||
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
|
||||
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
|
||||
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
|
||||
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
|
||||
|
||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||
inline size_t GCell::getDepth () const { return _depth; }
|
||||
inline int GCell::getRpCount () const { return _rpCount; }
|
||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||
|
||||
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
||||
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
|
||||
|
||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
||||
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
inline Flags& GCell::flags () { return _flags; }
|
||||
|
||||
inline DbU::Unit GCell::getXMax ( int shrink ) const
|
||||
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
|
||||
|
@ -494,25 +478,17 @@ namespace Anabatic {
|
|||
return lhs.getId() < rhs.getId();
|
||||
}
|
||||
|
||||
|
||||
// GCell::CompareByKey Inline Functions.
|
||||
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs )
|
||||
{ return lhs->getKey() < rhs->getKey(); }
|
||||
|
||||
|
||||
// GCell::Key Inline Functions.
|
||||
inline GCell::Key::Key ( const GCell* owner, size_t depth )
|
||||
: _gcell(owner)
|
||||
, _density(owner->getWDensity(depth,Flags::NoUpdate))
|
||||
{ }
|
||||
|
||||
inline GCell::Key::~Key ()
|
||||
{ if (isActive()) _gcell->clearClonedKey(); }
|
||||
|
||||
inline float GCell::Key::getDensity () const { return _density; }
|
||||
inline const GCell* GCell::Key::getGCell () const { return _gcell; }
|
||||
inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); }
|
||||
inline bool GCell::Key::isActive () const { return (this == _gcell->getLastClonedKey()); }
|
||||
inline bool GCell::Key::isSaturated () const { return _gcell->isSaturated(); }
|
||||
inline GCell::Key::Key ( GCell* owner, size_t depth ) : _gcell(owner), _density(owner->getWDensity(depth,Flags::NoUpdate)) {}
|
||||
inline float GCell::Key::getDensity () const { return _density; }
|
||||
inline GCell* GCell::Key::getGCell () const { return _gcell; }
|
||||
inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); }
|
||||
|
||||
inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs )
|
||||
{
|
||||
|
@ -522,22 +498,6 @@ namespace Anabatic {
|
|||
return lhs._gcell->getId() < rhs._gcell->getId();
|
||||
}
|
||||
|
||||
inline bool GCell::Key::Compare::operator() ( const GCell::Key* lhs, const GCell::Key* rhs )
|
||||
{
|
||||
//if (lhs->isSaturated() xor rhs->isSaturated()) return lhs->isSaturated();
|
||||
|
||||
float difference = lhs->_density - rhs->_density;
|
||||
if (difference != 0.0) return (difference < 0.0);
|
||||
|
||||
return lhs->_gcell->getId() < rhs->_gcell->getId();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "GCellKeyQueue".
|
||||
|
||||
typedef std::priority_queue< GCell::Key*, std::vector<GCell::Key*>, GCell::Key::Compare > GCellKeyQueue;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "GCellDensitySet".
|
||||
|
@ -582,3 +542,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::GCell);
|
||||
|
||||
#endif // ANABATIC_GCELL_H
|
||||
|
|
|
@ -221,11 +221,6 @@ namespace Anabatic {
|
|||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
AutoContact* _doHChannel ();
|
||||
|
@ -247,102 +242,73 @@ namespace Anabatic {
|
|||
+ ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \
|
||||
+ ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize))
|
||||
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
|
||||
, Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 )
|
||||
, Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
|
||||
, Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 )
|
||||
, Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 )
|
||||
, Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 )
|
||||
, Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
|
||||
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 )
|
||||
, Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
|
||||
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
|
||||
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
|
||||
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 )
|
||||
, Conn_1G_6M1 = CONNEXITY_VALUE( 1, 6, 0, 0, 0 , 0 )
|
||||
, Conn_1G_7M1 = CONNEXITY_VALUE( 1, 7, 0, 0, 0 , 0 )
|
||||
, Conn_1G_8M1 = CONNEXITY_VALUE( 1, 8, 0, 0, 0 , 0 )
|
||||
, Conn_1G_9M1 = CONNEXITY_VALUE( 1, 9, 0, 0, 0 , 0 )
|
||||
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
|
||||
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
|
||||
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
|
||||
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 )
|
||||
, Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
|
||||
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 )
|
||||
, Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
|
||||
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 )
|
||||
, Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
|
||||
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
|
||||
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 )
|
||||
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
|
||||
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
|
||||
, Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
|
||||
, Conn_2G_6M1 = CONNEXITY_VALUE( 2, 6, 0, 0, 0 , 0 )
|
||||
, Conn_2G_7M1 = CONNEXITY_VALUE( 2, 7, 0, 0, 0 , 0 )
|
||||
, Conn_2G_8M1 = CONNEXITY_VALUE( 2, 8, 0, 0, 0 , 0 )
|
||||
, Conn_2G_9M1 = CONNEXITY_VALUE( 2, 9, 0, 0, 0 , 0 )
|
||||
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
|
||||
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
|
||||
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
|
||||
, Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
|
||||
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 )
|
||||
, Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
|
||||
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 )
|
||||
, Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
|
||||
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
|
||||
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
|
||||
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
|
||||
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
|
||||
, Conn_3G_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 )
|
||||
, Conn_3G_6M1 = CONNEXITY_VALUE( 3, 6, 0, 0, 0 , 0 )
|
||||
, Conn_3G_7M1 = CONNEXITY_VALUE( 3, 7, 0, 0, 0 , 0 )
|
||||
, Conn_3G_8M1 = CONNEXITY_VALUE( 3, 8, 0, 0, 0 , 0 )
|
||||
, Conn_3G_9M1 = CONNEXITY_VALUE( 3, 9, 0, 0, 0 , 0 )
|
||||
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
|
||||
, Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
|
||||
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
|
||||
, Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
|
||||
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
|
||||
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
|
||||
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
|
||||
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
|
||||
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
|
||||
, Conn_4G_5M1 = CONNEXITY_VALUE( 4, 5, 0, 0, 0 , 0 )
|
||||
, Conn_4G_6M1 = CONNEXITY_VALUE( 4, 6, 0, 0, 0 , 0 )
|
||||
, Conn_4G_7M1 = CONNEXITY_VALUE( 4, 7, 0, 0, 0 , 0 )
|
||||
, Conn_4G_8M1 = CONNEXITY_VALUE( 4, 8, 0, 0, 0 , 0 )
|
||||
, Conn_4G_9M1 = CONNEXITY_VALUE( 4, 9, 0, 0, 0 , 0 )
|
||||
, Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
|
||||
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
|
||||
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
|
||||
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
|
||||
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
|
||||
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
||||
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 )
|
||||
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
|
||||
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
|
||||
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
|
||||
, Conn_1G_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 )
|
||||
, Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 )
|
||||
, Conn_2G_1M1_1PinM2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 1 )
|
||||
, Conn_2G_2M1_1PinM2 = CONNEXITY_VALUE( 2, 2, 1, 0, 0 , 1 )
|
||||
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
|
||||
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
|
||||
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 )
|
||||
, Conn_1G_1M1_1PinM3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 1 )
|
||||
, Conn_2G_1M1_1PinM3 = CONNEXITY_VALUE( 2, 1, 0, 1, 0 , 1 )
|
||||
, Conn_2G_2M1_1PinM3 = CONNEXITY_VALUE( 2, 2, 0, 1, 0 , 1 )
|
||||
, Conn_2G_3M1_1PinM3 = CONNEXITY_VALUE( 2, 3, 0, 1, 0 , 1 )
|
||||
, Conn_3G_1M1_1PinM3 = CONNEXITY_VALUE( 3, 1, 0, 1, 0 , 1 )
|
||||
, Conn_3G_2M1_1PinM3 = CONNEXITY_VALUE( 3, 2, 0, 1, 0 , 1 )
|
||||
, Conn_3G_3M1_1PinM3 = CONNEXITY_VALUE( 3, 3, 0, 1, 0 , 1 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
|
||||
, Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 )
|
||||
, Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
|
||||
, Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 )
|
||||
, Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 )
|
||||
, Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 )
|
||||
, Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
|
||||
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 )
|
||||
, Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
|
||||
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
|
||||
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
|
||||
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 )
|
||||
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
|
||||
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
|
||||
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
|
||||
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 )
|
||||
, Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
|
||||
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 )
|
||||
, Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
|
||||
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 )
|
||||
, Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
|
||||
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
|
||||
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 )
|
||||
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
|
||||
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
|
||||
, Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
|
||||
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
|
||||
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
|
||||
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
|
||||
, Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
|
||||
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 )
|
||||
, Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
|
||||
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 )
|
||||
, Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
|
||||
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
|
||||
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
|
||||
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
|
||||
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
|
||||
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
|
||||
, Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
|
||||
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
|
||||
, Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
|
||||
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
|
||||
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
|
||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
|
||||
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
|
||||
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
|
||||
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
|
||||
, Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
|
||||
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
|
||||
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
|
||||
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
|
||||
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
|
||||
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
||||
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 )
|
||||
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
|
||||
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
|
||||
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
|
||||
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
|
||||
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
|
||||
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 )
|
||||
};
|
||||
|
||||
#undef CONNEXITY_VALUE
|
||||
|
|
|
@ -28,41 +28,33 @@ namespace Anabatic {
|
|||
|
||||
class NetBuilderHV : public NetBuilder {
|
||||
public:
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
virtual bool _do_xG_1PinM3 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
virtual bool _do_xG_1PinM3 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace Anabatic {
|
|||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_SESSION_H
|
||||
#define ANABATIC_SESSION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
@ -95,13 +97,11 @@ namespace Anabatic {
|
|||
static inline size_t getDVerticalDepth ();
|
||||
static inline const Layer* getDVerticalLayer ();
|
||||
static inline DbU::Unit getDVerticalWidth ();
|
||||
static inline DbU::Unit getDPVerticalWidth ();
|
||||
static inline DbU::Unit getDVerticalPitch ();
|
||||
static inline DbU::Unit getDVerticalOffset ();
|
||||
static inline size_t getDHorizontalDepth ();
|
||||
static inline const Layer* getDHorizontalLayer ();
|
||||
static inline DbU::Unit getDHorizontalWidth ();
|
||||
static inline DbU::Unit getDPHorizontalWidth ();
|
||||
static inline DbU::Unit getDHorizontalPitch ();
|
||||
static inline DbU::Unit getDHorizontalOffset ();
|
||||
static inline size_t getDContactDepth ();
|
||||
|
@ -109,11 +109,6 @@ namespace Anabatic {
|
|||
static inline DbU::Unit getDContactWidth ();
|
||||
static inline DbU::Unit getDContactPitch ();
|
||||
static inline RoutingGauge* getRoutingGauge ();
|
||||
static inline bool isGLayer ( const Layer* );
|
||||
static inline bool isGMetal ( const Layer* );
|
||||
static inline bool isGContact ( const Layer* );
|
||||
static inline bool isGaugeLayer ( const Layer* );
|
||||
static inline RoutingLayerGauge* getLayerGauge ( const Layer* );
|
||||
static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
|
||||
static inline size_t getDepth ();
|
||||
static inline size_t getViaDepth ( const Layer* layer );
|
||||
|
@ -124,7 +119,6 @@ namespace Anabatic {
|
|||
static inline DbU::Unit getPitch ( size_t depth, Flags flags );
|
||||
static inline DbU::Unit getOffset ( size_t depth );
|
||||
static inline DbU::Unit getWireWidth ( size_t depth );
|
||||
static inline DbU::Unit getPWireWidth ( size_t depth );
|
||||
static inline DbU::Unit getViaWidth ( size_t depth );
|
||||
static inline Flags getDirection ( const Layer* );
|
||||
static inline DbU::Unit getPitch ( const Layer*, Flags flags );
|
||||
|
@ -132,7 +126,6 @@ namespace Anabatic {
|
|||
static inline DbU::Unit getWireWidth ( const Layer* );
|
||||
static inline DbU::Unit getViaWidth ( const Layer* );
|
||||
static inline DbU::Unit getExtensionCap ( const Layer* );
|
||||
static inline DbU::Unit getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode );
|
||||
static inline Point getNearestGridPoint ( Point, Box constraints );
|
||||
static inline size_t getSegmentStackSize ();
|
||||
static inline size_t getContactStackSize ();
|
||||
|
@ -174,7 +167,6 @@ namespace Anabatic {
|
|||
void _revalidateTopology ();
|
||||
virtual size_t _revalidate ();
|
||||
DbU::Unit _getPitch ( size_t depth, Flags flags ) const;
|
||||
DbU::Unit _getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode );
|
||||
Point _getNearestGridPoint ( Point, Box constraints );
|
||||
Record* _getRecord () const;
|
||||
string _getString () const;
|
||||
|
@ -243,24 +235,17 @@ namespace Anabatic {
|
|||
inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); }
|
||||
inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); }
|
||||
inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); }
|
||||
inline DbU::Unit Session::getDPVerticalWidth () { return getConfiguration()->getDPVerticalWidth(); }
|
||||
inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); }
|
||||
inline DbU::Unit Session::getDVerticalOffset () { return getConfiguration()->getDVerticalOffset(); }
|
||||
inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); }
|
||||
inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); }
|
||||
inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); }
|
||||
inline DbU::Unit Session::getDPHorizontalWidth () { return getConfiguration()->getDPHorizontalWidth(); }
|
||||
inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); }
|
||||
inline DbU::Unit Session::getDHorizontalOffset () { return getConfiguration()->getDHorizontalOffset(); }
|
||||
inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); }
|
||||
inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); }
|
||||
inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); }
|
||||
inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); }
|
||||
inline bool Session::isGLayer ( const Layer* layer ) { return getConfiguration()->isGLayer(layer); }
|
||||
inline bool Session::isGMetal ( const Layer* layer ) { return getConfiguration()->isGMetal(layer); }
|
||||
inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); }
|
||||
inline bool Session::isGaugeLayer ( const Layer* layer ) { return getRoutingGauge()->hasLayer(layer); }
|
||||
inline RoutingLayerGauge* Session::getLayerGauge ( const Layer* layer ) { return getRoutingGauge()->getLayerGauge(layer); }
|
||||
inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
|
||||
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
|
||||
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }
|
||||
|
@ -270,7 +255,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit Session::getPitch ( size_t depth, Flags flags=Flags::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); }
|
||||
inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); }
|
||||
inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); }
|
||||
inline DbU::Unit Session::getPWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerPWireWidth(depth); }
|
||||
inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); }
|
||||
inline DbU::Unit Session::getPitch ( const Layer* layer, Flags flags=Flags::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); }
|
||||
inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); }
|
||||
|
@ -279,7 +263,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); }
|
||||
inline Flags Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); }
|
||||
inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); }
|
||||
inline DbU::Unit Session::getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode ) { return get("getNearestTrackAxis()")->_getNearestTrackAxis(layer,axis,mode); }
|
||||
|
||||
inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); }
|
||||
inline void Session::_doglegReset () { _doglegs.clear(); }
|
||||
|
@ -293,3 +276,6 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::Session);
|
||||
|
||||
|
||||
#endif // ANABATIC_SESSION_H
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
|
||||
buildDir=${commonRoot}/build
|
||||
installDir=${commonRoot}/install
|
||||
|
||||
export ALLIANCE_TOP=${installDir}
|
||||
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
cd ${srcDir}
|
||||
# Skip doc generation to avoid pulling TeXLive in docker images.
|
||||
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
|
||||
./autostuff clean
|
||||
./autostuff
|
||||
mkdir -p ${buildDir}
|
||||
cd ${buildDir}
|
||||
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
|
||||
make -j1 install
|
|
@ -14,11 +14,11 @@ projects = [
|
|||
, { 'name' : "coriolis"
|
||||
, 'tools' : [ "bootstrap"
|
||||
, "lefdef"
|
||||
, "flute"
|
||||
, "coloquinte"
|
||||
, "vlsisapd"
|
||||
, "hurricane"
|
||||
, "crlcore"
|
||||
, "flute"
|
||||
, "etesian"
|
||||
, "anabatic"
|
||||
, "katana"
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
FindLibbfd.cmake
|
||||
FindQwt.cmake
|
||||
FindSphinx.cmake
|
||||
FindPelican.cmake
|
||||
GetGitRevisionDescription.cmake
|
||||
GetGitRevisionDescription.cmake.in
|
||||
)
|
||||
|
|
|
@ -95,13 +95,9 @@
|
|||
set(CXX_STANDARD "c++11")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
|
||||
#set(CMAKE_C_FLAGS_DEBUG " -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
|
||||
set(CMAKE_C_FLAGS_RELEASE " -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
|
||||
#set(CMAKE_C_FLAGS_RELEASE " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
|
||||
#set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
|
||||
|
||||
|
||||
#
|
||||
|
@ -278,8 +274,7 @@
|
|||
/usr/include
|
||||
PATH_SUFFIXES qwt )
|
||||
find_library(QWT_LIBRARY NAMES qwt-qt5 qwt
|
||||
PATHS /usr/lib64
|
||||
/usr/lib )
|
||||
PATHS /usr/lib${LIB_SUFFIX} )
|
||||
else()
|
||||
find_path(QWT_INCLUDE_DIR NAMES qwt.h
|
||||
PATHS /usr/include/qwt-qt4
|
||||
|
@ -289,8 +284,7 @@
|
|||
PATH_SUFFIXES qwt )
|
||||
find_library(QWT_LIBRARY NAMES qwt-qt4 qwt
|
||||
PATHS /opt/local/libexec/qt4/lib
|
||||
/usr/lib64
|
||||
/usr/lib )
|
||||
/usr/lib${LIB_SUFFIX} )
|
||||
endif()
|
||||
|
||||
if( QWT_INCLUDE_DIR AND QWT_LIBRARY)
|
||||
|
@ -419,7 +413,5 @@
|
|||
target_link_libraries( ${pytarget} ${pyDeplibs} )
|
||||
|
||||
install( TARGETS ${pytarget} DESTINATION ${PYTHON_SITE_PACKAGES} )
|
||||
if( NOT ("${pyIncludes}" STREQUAL "None") )
|
||||
install( FILES ${pyIncludes} DESTINATION ${inc_install_dir} )
|
||||
endif()
|
||||
endmacro( add_python_module )
|
||||
|
|
|
@ -63,7 +63,7 @@ FIND_PROGRAM(FLEX_EXECUTABLE flex DOC "path to the flex executable")
|
|||
MARK_AS_ADVANCED(FLEX_EXECUTABLE)
|
||||
|
||||
FIND_LIBRARY(FL_LIBRARY NAMES fl
|
||||
PATHS /usr/lib64 lib DOC "path to the fl library")
|
||||
PATHS /usr/lib${LIB_SUFFIX} DOC "path to the fl library")
|
||||
SET(FLEX_LIBRARIES ${FL_LIBRARY})
|
||||
|
||||
IF(FLEX_EXECUTABLE)
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
|
||||
find_path( LEFDEF_LIBRARY_DIR NAMES "libdef.so"
|
||||
PATHS ${LEFDEF_SEARCH_PATH}
|
||||
PATH_SUFFIXES "lib64" "lib"
|
||||
PATH_SUFFIXES "lib${LIB_SUFFIX}"
|
||||
DOC "The ${LEFDEF_LIBRARY_DIR_DESCRIPTION}" )
|
||||
message( STATUS "LEFDEF_LIBRARY_DIR: ${LEFDEF_LIBRARY_DIR}" )
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
find_program( PELICAN_EXECUTABLE NAMES pelican
|
||||
HINTS $ENV{PELICAN_DIR}
|
||||
PATH_SUFFIXES bin
|
||||
DOC "Pelican blog generator"
|
||||
)
|
||||
|
||||
include( FindPackageHandleStandardArgs )
|
||||
find_package_handle_standard_args( Pelican DEFAULT_MSG PELICAN_EXECUTABLE )
|
||||
mark_as_advanced( PELICAN_EXECUTABLE )
|
|
@ -67,41 +67,77 @@ def guessOs ():
|
|||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
|
||||
if osSlsoc7x_64.match(lines[0]): osType = "Linux.el7_64"
|
||||
libDir="lib"
|
||||
if osSlsoc7x_64.match(lines[0]):
|
||||
osType = "Linux.el7_64"
|
||||
libDir = "lib64"
|
||||
elif osSlsoc6x_64.match(lines[0]):
|
||||
osType = "Linux.slsoc6x_64"
|
||||
libDir = "lib64"
|
||||
useDevtoolset = True
|
||||
elif osSlsoc6x.match(lines[0]):
|
||||
osType = "Linux.slsoc6x"
|
||||
useDevtoolset = True
|
||||
elif osSLSoC5x_64 .match(lines[0]): osType = "Linux.SLSoC5x_64"
|
||||
elif osSLSoC5x .match(lines[0]): osType = "Linux.SLSoC5x"
|
||||
elif osFedora_64 .match(lines[0]): osType = "Linux.fc_64"
|
||||
elif osFedora .match(lines[0]): osType = "Linux.fc"
|
||||
elif osUbuntu1004 .match(lines[0]): osType = "Linux.Ubuntu1004"
|
||||
elif osUbuntu1004_64 .match(lines[0]): osType = "Linux.Ubuntu1004_64"
|
||||
elif osLinux_64 .match(lines[0]): osType = "Linux.x86_64"
|
||||
elif osLinux .match(lines[0]): osType = "Linux.i386"
|
||||
elif osFreeBSD8x_64 .match(lines[0]): osType = "FreeBSD.8x.x86_64"
|
||||
elif osFreeBSD8x_amd64.match(lines[0]): osType = "FreeBSD.8x.amd64"
|
||||
elif osFreeBSD8x .match(lines[0]): osType = "FreeBSD.8x.i386"
|
||||
elif osDarwin .match(lines[0]): osType = "Darwin"
|
||||
elif osCygwinW7_64 .match(lines[0]): osType = "Cygwin.W7_64"
|
||||
elif osCygwinW7 .match(lines[0]): osType = "Cygwin.W7"
|
||||
elif osCygwinW8_64 .match(lines[0]): osType = "Cygwin.W8_64"
|
||||
elif osCygwinW8 .match(lines[0]): osType = "Cygwin.W8"
|
||||
elif osCygwinW10_64 .match(lines[0]): osType = "Cygwin.W10_64"
|
||||
elif osCygwinW10 .match(lines[0]): osType = "Cygwin.W10"
|
||||
elif osSLSoC5x_64.match(lines[0]):
|
||||
osType = "Linux.SLSoC5x_64"
|
||||
libDir = "lib64"
|
||||
elif osSLSoC5x.match(lines[0]):
|
||||
osType = "Linux.SLSoC5x"
|
||||
elif osFedora_64.match(lines[0]):
|
||||
osType = "Linux.fc_64"
|
||||
libDir = "lib64"
|
||||
elif osFedora.match(lines[0]):
|
||||
osType = "Linux.fc"
|
||||
elif osUbuntu1004.match(lines[0]):
|
||||
osType = "Linux.Ubuntu1004"
|
||||
elif osUbuntu1004_64.match(lines[0]):
|
||||
osType = "Linux.Ubuntu1004_64"
|
||||
libDir = "lib64"
|
||||
elif osLinux_64.match(lines[0]):
|
||||
osType = "Linux.x86_64"
|
||||
if(os.path.exists("/usr/lib64/")):
|
||||
libDir = "lib64"
|
||||
elif osLinux.match(lines[0]):
|
||||
osType = "Linux.i386"
|
||||
elif osFreeBSD8x_64.match(lines[0]):
|
||||
osType = "FreeBSD.8x.x86_64"
|
||||
libDir = "lib64"
|
||||
elif osFreeBSD8x_amd64.match(lines[0]):
|
||||
osType = "FreeBSD.8x.amd64"
|
||||
libDir = "lib64"
|
||||
elif osFreeBSD8x.match(lines[0]):
|
||||
osType = "FreeBSD.8x.i386"
|
||||
elif osDarwin.match(lines[0]):
|
||||
osType = "Darwin"
|
||||
elif osCygwinW7_64.match(lines[0]):
|
||||
osType = "Cygwin.W7_64"
|
||||
libDir = "lib64"
|
||||
elif osCygwinW7.match(lines[0]):
|
||||
osType = "Cygwin.W7"
|
||||
elif osCygwinW8_64.match(lines[0]):
|
||||
osType = "Cygwin.W8_64"
|
||||
libDir = "lib64"
|
||||
elif osCygwinW8.match(lines[0]):
|
||||
osType = "Cygwin.W8"
|
||||
elif osCygwinW10_64.match(lines[0]):
|
||||
osType = "Cygwin.W10_64"
|
||||
libDir = "lib64"
|
||||
elif osCygwinW10.match(lines[0]):
|
||||
osType = "Cygwin.W10"
|
||||
else:
|
||||
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
|
||||
osType = uname.stdout.readlines()[0][:-1]
|
||||
|
||||
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
|
||||
print " (using: \"%s\")" % osType
|
||||
|
||||
ldLibraryPath = os.getenv('LD_LIBRARY_PATH')
|
||||
if ldLibraryPath and 'devtoolset' in ldLibraryPath: useDevtoolset = False
|
||||
|
||||
if libDir == 'lib64' and not os.path.exists('/usr/lib64'):
|
||||
libDir = 'lib'
|
||||
|
||||
return (osType,useDevtoolset)
|
||||
return (osType,libDir,useDevtoolset)
|
||||
|
||||
|
||||
def guessShell ():
|
||||
|
@ -134,11 +170,11 @@ def guessShell ():
|
|||
|
||||
if __name__ == "__main__":
|
||||
|
||||
osType,useDevtoolset = guessOs()
|
||||
buildType = "Release"
|
||||
linkType = "Shared"
|
||||
rootDir = None
|
||||
shellBin, isBourneShell = guessShell()
|
||||
osType,libDir,useDevtoolset = guessOs()
|
||||
buildType = "Release"
|
||||
linkType = "Shared"
|
||||
rootDir = None
|
||||
shellBin, isBourneShell = guessShell()
|
||||
|
||||
parser = optparse.OptionParser ()
|
||||
# Build relateds.
|
||||
|
@ -151,7 +187,6 @@ if __name__ == "__main__":
|
|||
parser.add_option ( "--shared" , action="store_true" , dest="shared" )
|
||||
parser.add_option ( "--no-python" , action="store_true" , dest="nopython" )
|
||||
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" )
|
||||
parser.add_option ( "--remove" , action="store_true" , dest="remove" )
|
||||
( options, args ) = parser.parse_args ()
|
||||
|
||||
if options.release: buildType = "Release"
|
||||
|
@ -172,32 +207,6 @@ if __name__ == "__main__":
|
|||
strippedLibraryPath = scrubPath( "LD_LIBRARY_PATH" )
|
||||
strippedPythonPath = scrubPath( "PYTHONPATH" )
|
||||
|
||||
if options.remove:
|
||||
shellScript = 'echo "Removing Coriolis environment";'
|
||||
if osType == "Darwin":
|
||||
ldVar = 'DYLD_LIBRARY_PATH'
|
||||
else:
|
||||
ldVar = 'LD_LIBRARY_PATH'
|
||||
|
||||
if isBourneShell:
|
||||
shellScript += 'export PATH={};hash -r;'.format(strippedPath)
|
||||
shellScript += 'BOOTSTRAP_TOP="";CORIOLIS_TOP="";export -n BOOTSTRAP_TOP CORIOLIS_TOP;'
|
||||
if strippedLibraryPath:
|
||||
shellScript += 'export {}={};'.format(ldVar, strippedLibraryPath)
|
||||
else:
|
||||
shellScript += '{0}=""; export -n {0};'.format(ldVar)
|
||||
else:
|
||||
shellScript += 'setenv PATH {};rehash;'.format(strippedPath)
|
||||
shellScript += 'unsetenv BOOTSTRAP_TOP CORIOLIS_TOP;'
|
||||
if strippedLibraryPath:
|
||||
shellScript += 'setenv {} {};'.format(ldVar, strippedLibraryPath)
|
||||
else:
|
||||
shellScript += 'unsetenv {};'.format(ldVar)
|
||||
|
||||
print(shellScript)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
shellScriptSh = \
|
||||
'echo "%(MESSAGE)s";' \
|
||||
'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \
|
||||
|
@ -251,37 +260,29 @@ if __name__ == "__main__":
|
|||
shellMessage = "Using user-selected Coriolis 2 (%s)" % rootDir
|
||||
|
||||
if osType.startswith("Cygwin"):
|
||||
strippedPath = "%s/lib:%s" % ( coriolisTop, libDir, strippedPath )
|
||||
strippedPath = "%s/%s:%s" % ( coriolisTop, libDir, strippedPath )
|
||||
|
||||
absLibDir = "%s/%s" % ( coriolisTop, libDir )
|
||||
strippedPath = "%s/bin:%s" % ( coriolisTop, strippedPath )
|
||||
strippedLibraryPath = "%s:%s" % ( absLibDir , strippedLibraryPath )
|
||||
|
||||
if not os.path.exists(coriolisTop):
|
||||
print 'echo "[ERROR] coriolisEnv.py, top directory <%s> do not exists."' % coriolisTop
|
||||
sys.exit( 1 )
|
||||
|
||||
for lib in [ 'lib64', 'lib' ]:
|
||||
libDir = lib
|
||||
absLibDir = '{0}/{1}'.format( coriolisTop, lib )
|
||||
if os.path.isdir(absLibDir): break
|
||||
libDir = None
|
||||
|
||||
if libDir is None:
|
||||
print 'echo "[ERROR] coriolisEnv.py, library directory not found."'
|
||||
sys.exit( 1 )
|
||||
|
||||
strippedPath = "%s/bin:%s" % ( coriolisTop, strippedPath )
|
||||
strippedLibraryPath = "%s:%s" % ( absLibDir , strippedLibraryPath )
|
||||
|
||||
if not options.nopython:
|
||||
pyVersion = sys.version_info
|
||||
version = "%d.%d" % (pyVersion[0],pyVersion[1])
|
||||
|
||||
sitePackagesDir = "sitePackageDir_has_been_not_found"
|
||||
for pyPackageDir in [ "%s/python%s/site-packages" % (absLibDir,version)
|
||||
, "%s/python%s/dist-packages" % (absLibDir,version)
|
||||
, "%s/%s/site-packages" % (absLibDir,version)
|
||||
]:
|
||||
if os.path.isdir(pyPackageDir):
|
||||
sitePackagesDir = pyPackageDir
|
||||
break
|
||||
if osType.startswith("Linux.SL") \
|
||||
or osType.startswith("Linux.sl") \
|
||||
or osType.startswith("Linux.el") \
|
||||
or osType.startswith("Linux.fc") \
|
||||
or osType.startswith("Cygwin"):
|
||||
sitePackagesDir = "%s/python%s/site-packages" % (absLibDir,version)
|
||||
elif osType.startswith("Darwin"):
|
||||
sitePackagesDir = "%s/%s/site-packages" % (absLibDir,version)
|
||||
else:
|
||||
sitePackagesDir = "%s/python%s/dist-packages" % (absLibDir,version)
|
||||
|
||||
strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
FROM debian10.coriolis
|
||||
|
||||
COPY root/dot.bashrc /root/.bashrc
|
||||
|
||||
CMD [ "/bin/bash", "-i" ]
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
FROM debian10.system
|
||||
|
||||
COPY root/socInstaller.py /root/socInstaller.py
|
||||
RUN mkdir -p coriolis-2.x/src \
|
||||
&& git clone https://github.com/m-labs/nmigen.git \
|
||||
&& cd nmigen \
|
||||
&& python3 setup.py develop \
|
||||
&& /root/socInstaller.py --docker --profile=Debian10 --do-yosys --do-alliance --do-coriolis
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
FROM debian10.libresoc
|
||||
|
||||
CMD [ "/bin/bash", "-i" ]
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
FROM debian10.coriolis
|
||||
|
||||
# Cannot clone directly from LibreSOC repository as I need my
|
||||
# ssh key that I cannot forward to the docker build process.
|
||||
#
|
||||
# git clone ssh://gitolite3@libre-riscv.org:922/soclayout.git
|
||||
|
||||
COPY ./root/soclayout /root/coriolis-2.x/src/soclayout
|
||||
RUN cd /root/coriolis-2.x/src/soclayout \
|
||||
&& git checkout 75e03eb
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
FROM debian:buster-slim
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install build-essential binutils-dev \
|
||||
git cmake bison flex gcc python-dev \
|
||||
libboost-all-dev libboost-python-dev \
|
||||
zlib1g-dev libxml2-dev rapidjson-dev libbz2-dev \
|
||||
qt4-dev-tools libqwt-dev python-qt4 \
|
||||
python3-setuptools \
|
||||
\
|
||||
autotools-dev automake \
|
||||
libxt-dev libxpm-dev libmotif-dev \
|
||||
\
|
||||
tcl tcl-dev libffi6 libffi-dev libreadline-dev \
|
||||
\
|
||||
vim \
|
||||
&& apt-get clean
|
||||
|
||||
# If you want to build Alliance documentation, install those LaTeX
|
||||
# packages:
|
||||
# transfig texlive texlive-latex-extra
|
||||
# texlive-plain-generic texlive-pictures
|
||||
# imagemagick
|
||||
#
|
||||
# The packaged yosys 0.8 is too old to work with nMigen, must be 0.9.
|
||||
# yosys
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
systemImage="debian10.system"
|
||||
coriolisImage="debian10.coriolis"
|
||||
bashImage="debian10.bash"
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
|
||||
buildDir=${commonRoot}/build
|
||||
installDir=${commonRoot}/install
|
||||
|
||||
export ALLIANCE_TOP=${installDir}
|
||||
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
cd ${srcDir}
|
||||
# Skip doc generation to avoid pulling TeXLive in docker images.
|
||||
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
|
||||
./autostuff clean
|
||||
./autostuff
|
||||
mkdir -p ${buildDir}
|
||||
cd ${buildDir}
|
||||
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
|
||||
make -j1 install
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
echo "Running /root/.bashrc"
|
||||
|
||||
for archDir in `ls /root/coriolis-2.x/`; do
|
||||
if [ "$archDir" = "src" ]; then continue; fi
|
||||
break
|
||||
done
|
||||
echo "Found Coriolis architecture directory \"${archDir}\"."
|
||||
|
||||
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
|
||||
. ${installDir}/etc/profile.d/alc_env.sh
|
||||
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
|
||||
|
||||
export QT_X11_NO_MITSHM=1
|
|
@ -1,650 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC 2015-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s I n s t a l l e r |
|
||||
# | |
|
||||
# | Authors : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./socInstaller.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
#
|
||||
# WARNING:
|
||||
# This script has been designed only for internal use in the
|
||||
# LIP6/CIAN department. If you want to use it you will need to
|
||||
# change the hardwired configuration.
|
||||
|
||||
|
||||
showTrace = True
|
||||
|
||||
try:
|
||||
import sys
|
||||
import os.path
|
||||
import shutil
|
||||
import optparse
|
||||
import time
|
||||
import traceback
|
||||
import distutils.sysconfig
|
||||
import subprocess
|
||||
import socket
|
||||
import re
|
||||
import bz2
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.application import MIMEApplication
|
||||
except ImportError, e:
|
||||
module = str(e).split()[-1]
|
||||
|
||||
|
||||
class ErrorMessage ( Exception ):
|
||||
|
||||
def __init__ ( self, code, *arguments ):
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
if not isinstance(self._errors,list):
|
||||
return "[ERROR] %s" % self._errors
|
||||
|
||||
formatted = "\n"
|
||||
for i in range(len(self._errors)):
|
||||
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
|
||||
else: formatted += " %s" % self._errors[i]
|
||||
if i+1 < len(self._errors): formatted += "\n"
|
||||
return formatted
|
||||
|
||||
def addMessage ( self, message ):
|
||||
if not isinstance(self._errors,list):
|
||||
self._errors = [ self._errors ]
|
||||
if isinstance(message,list):
|
||||
for line in message:
|
||||
self._errors += [ line ]
|
||||
else:
|
||||
self._errors += [ message ]
|
||||
return
|
||||
|
||||
def terminate ( self ):
|
||||
print self
|
||||
sys.exit(self._code)
|
||||
|
||||
@property
|
||||
def code ( self ): return self._code
|
||||
|
||||
|
||||
class BadBinary ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, binary ):
|
||||
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
|
||||
return
|
||||
|
||||
|
||||
class BadReturnCode ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, status ):
|
||||
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
|
||||
return
|
||||
|
||||
|
||||
class Command ( object ):
|
||||
|
||||
def __init__ ( self, arguments, fdLog=None ):
|
||||
self.arguments = arguments
|
||||
self.fdLog = fdLog
|
||||
|
||||
if self.fdLog != None and not isinstance(self.fdLog,file):
|
||||
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
|
||||
return
|
||||
|
||||
def _argumentsToStr ( self, arguments ):
|
||||
s = ''
|
||||
for argument in arguments:
|
||||
if argument.find(' ') >= 0: s += ' "' + argument + '"'
|
||||
else: s += ' ' + argument
|
||||
return s
|
||||
|
||||
def log ( self, text ):
|
||||
print text[:-1]
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if isinstance(self.fdLog,file):
|
||||
self.fdLog.write( text )
|
||||
self.fdLog.flush()
|
||||
return
|
||||
|
||||
def execute ( self ):
|
||||
global conf
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
homeDir = os.environ['HOME']
|
||||
workDir = os.getcwd()
|
||||
if homeDir.startswith(homeDir):
|
||||
workDir = '~' + workDir[ len(homeDir) : ]
|
||||
user = 'root'
|
||||
if os.environ.has_key('USER'): user = os.environ['USER']
|
||||
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
|
||||
|
||||
try:
|
||||
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
|
||||
print self.arguments
|
||||
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
|
||||
self.log( line )
|
||||
except OSError, e:
|
||||
raise BadBinary( self.arguments[0] )
|
||||
|
||||
(pid,status) = os.waitpid( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
raise BadReturnCode( status )
|
||||
|
||||
return
|
||||
|
||||
|
||||
class CommandArg ( object ):
|
||||
|
||||
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
|
||||
self.command = command
|
||||
self.host = host
|
||||
self.wd = wd
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
s = ''
|
||||
if self.wd: s = 'cd %s && ' % self.wd
|
||||
|
||||
for i in range(len(self.command)):
|
||||
if i: s += ' '
|
||||
s += self.command[i]
|
||||
return s
|
||||
|
||||
def getArgs ( self ):
|
||||
if not self.host: return self.command
|
||||
return [ 'ssh', self.host, str(self) ]
|
||||
|
||||
def execute ( self ):
|
||||
if not self.host and self.wd: os.chdir( self.wd )
|
||||
Command( self.getArgs(), self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class YosysCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, yosysBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ yosysBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class AllianceCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, alcBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class CoriolisCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ ccbBin
|
||||
, '--root='+rootDir
|
||||
, '--project=coriolis'
|
||||
, '--make=-j%d install' % threads
|
||||
] + otherArgs
|
||||
, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class BenchsCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, benchsDir, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
|
||||
class GitRepository ( object ):
|
||||
|
||||
@staticmethod
|
||||
def getLocalRepository ( url ):
|
||||
localRepo = url.split( '/' )[-1]
|
||||
if localRepo.endswith('.git'):
|
||||
localRepo = localRepo[:-4]
|
||||
return localRepo
|
||||
|
||||
def __init__ ( self, url, cloneDir, fdLog=None ):
|
||||
self.url = url
|
||||
self.cloneDir = cloneDir
|
||||
self.localRepo = GitRepository.getLocalRepository( url )
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
@property
|
||||
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
|
||||
|
||||
def removeLocalRepo ( self ):
|
||||
if os.path.isdir(self.localRepoDir):
|
||||
print 'Removing Git local repository: <%s>' % self.localRepoDir
|
||||
shutil.rmtree( self.localRepoDir )
|
||||
return
|
||||
|
||||
def clone ( self ):
|
||||
print 'Clone/pull from:', self.url
|
||||
if not os.path.isdir(self.cloneDir):
|
||||
os.makedirs( self.cloneDir )
|
||||
|
||||
if not os.path.isdir(self.localRepoDir):
|
||||
os.chdir( self.cloneDir )
|
||||
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
|
||||
else:
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'pull' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def checkout ( self, branch ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
PrimaryNames = \
|
||||
[ 'sender' , 'receivers'
|
||||
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
|
||||
, 'homeDir' , 'masterHost'
|
||||
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
|
||||
, 'rmSource' , 'rmBuild'
|
||||
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
|
||||
, 'success' , 'rcode'
|
||||
]
|
||||
SecondaryNames = \
|
||||
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'yosysBin', 'alcBin', 'ccbBin', 'benchsDir'
|
||||
]
|
||||
|
||||
def __init__ ( self ):
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
|
||||
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
|
||||
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
|
||||
self._homeDir = os.environ['HOME']
|
||||
self._debugArg = ''
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = True
|
||||
self._doYosys = False
|
||||
self._doAlliance = False
|
||||
self._doCoriolis = False
|
||||
self._doBenchs = False
|
||||
self._doSendReport = False
|
||||
self._nightlyMode = False
|
||||
self._dockerMode = False
|
||||
self._chrootMode = None
|
||||
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._ccbBin = None
|
||||
self._benchsDir = None
|
||||
self._masterHost = self._detectMasterHost()
|
||||
self._success = False
|
||||
self._rcode = 0
|
||||
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute == 'masterHost' or attribute == '_masterHost':
|
||||
if value == 'lepka':
|
||||
print 'Never touch the Git tree when running on <lepka>.'
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = False
|
||||
self._doSendReport = False
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'homeDir': value = os.path.expanduser(value)
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
def _updateSecondaries ( self ):
|
||||
if self._nightlyMode:
|
||||
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
|
||||
else:
|
||||
self._rootDir = self._homeDir + '/coriolis-2.x'
|
||||
self._srcDir = self._rootDir + '/src'
|
||||
self._logDir = self._srcDir + '/logs'
|
||||
self._yosysBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/yosysInstaller.sh'
|
||||
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
|
||||
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
|
||||
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
|
||||
self._masterHost = self._detectMasterHost()
|
||||
return
|
||||
|
||||
def _detectMasterHost ( self ):
|
||||
if self._chrootMode is None: return 'unknown'
|
||||
if self._chrootMode: return 'chrooted-host'
|
||||
|
||||
masterHost = 'unknown'
|
||||
hostname = socket.gethostname()
|
||||
hostAddr = socket.gethostbyname(hostname)
|
||||
|
||||
if hostname == 'lepka' and hostAddr == '127.0.0.1':
|
||||
masterHost = 'lepka'
|
||||
else:
|
||||
masterHost = hostname.split('.')[0]
|
||||
return masterHost
|
||||
|
||||
def openLog ( self, stem ):
|
||||
if not os.path.isdir(self._logDir):
|
||||
os.makedirs( self._logDir )
|
||||
|
||||
index = 0
|
||||
timeTag = time.strftime( "%Y.%m.%d" )
|
||||
while True:
|
||||
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
|
||||
if not os.path.isfile(logFile):
|
||||
print "Report log: <%s>" % logFile
|
||||
break
|
||||
index += 1
|
||||
fd = open( logFile, "w" )
|
||||
self._logs[stem] = logFile
|
||||
self._fds [stem] = fd
|
||||
return
|
||||
|
||||
def closeLogs ( self ):
|
||||
for fd in self._fds.values():
|
||||
if fd: fd.close()
|
||||
return
|
||||
|
||||
def compressLogs ( self ):
|
||||
for log in self._logs.values():
|
||||
if not log: continue
|
||||
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
|
||||
bzfd.close()
|
||||
fd.close()
|
||||
|
||||
os.unlink( log )
|
||||
return
|
||||
|
||||
def getCommands ( self, target ):
|
||||
commands = []
|
||||
|
||||
if self.doYosys:
|
||||
if not os.path.isfile( self.yosysBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <yosysInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.yosysBin
|
||||
] )
|
||||
commands.append( YosysCommand( self.yosysBin, fdLog=self.fds['yosys'] ) )
|
||||
|
||||
if self.doAlliance:
|
||||
if not os.path.isfile( self.alcBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.alcBin
|
||||
] )
|
||||
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
|
||||
|
||||
if self.doCoriolis:
|
||||
if not os.path.isfile( self.ccbBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
|
||||
, ' <%s>' % self.ccbBin
|
||||
] )
|
||||
|
||||
otherArgs = []
|
||||
if self.debugArg: otherArgs.append( self.debugArg )
|
||||
|
||||
if target == 'SL7_64':
|
||||
otherArgs.append( '--project=support' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'SL6_64' or target == 'SL6':
|
||||
otherArgs.append( '--project=support' )
|
||||
otherArgs.append( '--devtoolset=8' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
|
||||
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
|
||||
|
||||
if self.doBenchs:
|
||||
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
|
||||
return commands
|
||||
|
||||
|
||||
class Report ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = conf
|
||||
|
||||
commaspace = ', '
|
||||
date = time.strftime( "%A %d %B %Y" )
|
||||
stateText = 'FAILED'
|
||||
modeText = 'SoC installation'
|
||||
if self.conf.success: stateText = 'SUCCESS'
|
||||
if self.conf.nightlyMode: modeText = 'Nightly build'
|
||||
|
||||
self.message = MIMEMultipart()
|
||||
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
|
||||
self.message['From' ] = self.conf.sender
|
||||
self.message['To' ] = commaspace.join( self.conf.receivers )
|
||||
self.attachements = []
|
||||
|
||||
self.mainText = '\n'
|
||||
self.mainText += 'Salut le Crevard,\n'
|
||||
self.mainText += '\n'
|
||||
if self.conf.nightlyMode:
|
||||
self.mainText += 'This is the nightly build report of Coriolis.\n'
|
||||
else:
|
||||
self.mainText += 'SoC installer report of Coriolis.\n'
|
||||
self.mainText += '%s\n' % date
|
||||
self.mainText += '\n'
|
||||
if self.conf.success:
|
||||
self.mainText += 'Build was SUCCESSFUL\n'
|
||||
else:
|
||||
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
|
||||
self.mainText += '\n'
|
||||
self.mainText += 'Complete log file(s) can be found here:\n'
|
||||
return
|
||||
|
||||
def attachLog ( self, logFile ):
|
||||
if not logFile: return
|
||||
|
||||
fd = open( logFile, 'rb' )
|
||||
try:
|
||||
fd.seek( -1024*100, os.SEEK_END )
|
||||
except IOError, e:
|
||||
pass
|
||||
tailLines = ''
|
||||
for line in fd.readlines()[1:]:
|
||||
tailLines += line
|
||||
fd.close()
|
||||
self.mainText += ' <%s>\n' % logFile
|
||||
|
||||
attachement = MIMEApplication(tailLines)
|
||||
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
|
||||
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
|
||||
def send ( self ):
|
||||
self.message.attach( MIMEText(self.mainText) )
|
||||
for attachement in self.attachements:
|
||||
self.message.attach( attachement )
|
||||
|
||||
print "Sending mail report to:"
|
||||
for receiver in self.conf.receivers: print ' <%s>' % receiver
|
||||
session = smtplib.SMTP( 'localhost' )
|
||||
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
|
||||
session.quit()
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# <socInstaller> Main Part.
|
||||
|
||||
|
||||
parser = optparse.OptionParser ()
|
||||
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
|
||||
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
|
||||
parser.add_option ( "--do-yosys" , action="store_true" , dest="doYosys" , help="Rebuild Yosys." )
|
||||
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
|
||||
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
|
||||
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
|
||||
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
|
||||
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
|
||||
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
|
||||
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
|
||||
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
|
||||
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
|
||||
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
|
||||
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
|
||||
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
|
||||
conf = Configuration()
|
||||
|
||||
try:
|
||||
if options.debug: conf.debugArg = '--debug'
|
||||
if options.nightly: conf.nightlyMode = True
|
||||
if options.docker: conf.dockerMode = True
|
||||
if options.chroot: conf.chrootMode = True
|
||||
if options.noGit: conf.doGit = False
|
||||
if options.doYosys: conf.doYosys = True
|
||||
if options.doAlliance: conf.doAlliance = True
|
||||
if options.doCoriolis: conf.doCoriolis = True
|
||||
if options.benchs: conf.doBenchs = True
|
||||
if options.doReport: conf.doSendReport = True
|
||||
if options.rmSource or options.rmAll: conf.rmSource = True
|
||||
if options.rmBuild or options.rmAll: conf.rmBuild = True
|
||||
|
||||
|
||||
if conf.doYosys: conf.openLog( 'yosys' )
|
||||
if conf.doAlliance: conf.openLog( 'alliance' )
|
||||
if conf.doCoriolis: conf.openLog( 'coriolis' )
|
||||
if conf.doBenchs: conf.openLog( 'benchs' )
|
||||
|
||||
if conf.dockerMode: os.environ['USER'] = 'root'
|
||||
|
||||
gitSupports = []
|
||||
for supportRepo in conf.supportRepos:
|
||||
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
|
||||
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
|
||||
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
|
||||
|
||||
if conf.doAlliance:
|
||||
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
|
||||
|
||||
if conf.doGit:
|
||||
for gitSupport in gitSupports:
|
||||
if conf.rmSource: gitSupport.removeLocalRepo()
|
||||
gitSupport.clone()
|
||||
#if gitSupport.url.endswith('rapidjson'):
|
||||
# gitSupport.checkout( 'a1c4f32' )
|
||||
|
||||
if conf.doAlliance:
|
||||
if conf.rmSource: gitAlliance.removeLocalRepo()
|
||||
gitAlliance.clone ()
|
||||
#gitAlliance.checkout( 'devel' )
|
||||
|
||||
if conf.doCoriolis:
|
||||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
|
||||
if conf.rmBuild:
|
||||
for entry in os.listdir(conf.rootDir):
|
||||
if entry.startswith('Linux.'):
|
||||
buildDir = conf.rootDir+'/'+entry
|
||||
print 'Removing OS build directory: <%s>' % buildDir
|
||||
shutil.rmtree( buildDir )
|
||||
|
||||
commands = conf.getCommands( options.profile )
|
||||
for command in commands:
|
||||
if command.host:
|
||||
print 'Executing command on remote host <%s>:' % host
|
||||
else:
|
||||
print 'Executing command on *local* host:'
|
||||
print ' %s' % str(command)
|
||||
command.execute()
|
||||
|
||||
conf.closeLogs()
|
||||
|
||||
conf.success = True
|
||||
|
||||
except ErrorMessage, e:
|
||||
print e
|
||||
conf.closeLogs()
|
||||
conf.success = False
|
||||
|
||||
if showTrace:
|
||||
print '\nPython stack trace:'
|
||||
traceback.print_tb( sys.exc_info()[2] )
|
||||
conf.rcode = e.code
|
||||
|
||||
if conf.doSendReport:
|
||||
report = Report( conf )
|
||||
report.attachLog( conf.logs['coriolis' ] )
|
||||
report.attachLog( conf.logs['benchs' ] )
|
||||
report.send()
|
||||
|
||||
conf.compressLogs()
|
||||
|
||||
sys.exit( conf.rcode )
|
|
@ -1 +0,0 @@
|
|||
Subproject commit bd6b78003c0cc6579fbad73593e69f2714f3a770
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
FROM sl7.coriolis
|
||||
|
||||
COPY root/dot.bashrc /root/.bashrc
|
||||
|
||||
CMD [ "/bin/bash", "-i" ]
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
FROM sl7.system
|
||||
|
||||
COPY root/socInstaller.py /root/socInstaller.py
|
||||
RUN /root/socInstaller.py --docker --profile=SL7_64 --do-alliance --do-coriolis --benchs
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
FROM scientificlinux/sl:latest
|
||||
|
||||
RUN yum -y update \
|
||||
&& yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
|
||||
&& yum -y install git cmake bison flex gcc-c++ libstdc++-devel \
|
||||
make binutils-devel \
|
||||
boost-devel boost-python boost-filesystem \
|
||||
boost-regex boost-wave \
|
||||
python-devel libxml2-devel bzip2-devel \
|
||||
qt-devel PyQt4 \
|
||||
\
|
||||
autoconf automake libtool \
|
||||
libX11-devel libXt-devel libXpm-devel \
|
||||
motif motif-devel \
|
||||
\
|
||||
python36-six \
|
||||
vim-x11 \
|
||||
&& yum -y install http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/qwt-6.1.2-4.fc23.x86_64.rpm \
|
||||
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/qwt-devel-6.1.2-4.fc23.x86_64.rpm \
|
||||
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/yosys-0.9-1.el7.soc.x86_64.rpm \
|
||||
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/python3-pyvcd-0.1.7-git2302c99.1.el7.soc.x86_64.rpm \
|
||||
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/python3-nmigen-0.1-git57d95b7.1.el7.soc.x86_64.rpm \
|
||||
&& yum clean all
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
systemImage="sl7.system"
|
||||
coriolisImage="sl7.coriolis"
|
||||
bashImage="sl7.bash"
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
|
||||
buildDir=${commonRoot}/build
|
||||
installDir=${commonRoot}/install
|
||||
|
||||
export ALLIANCE_TOP=${installDir}
|
||||
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
cd ${srcDir}
|
||||
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
|
||||
./autostuff clean
|
||||
./autostuff
|
||||
mkdir -p ${buildDir}
|
||||
cd ${buildDir}
|
||||
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
|
||||
make -j1 install
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
echo "Running /root/.bashrc"
|
||||
|
||||
for archDir in `ls /root/coriolis-2.x/`; do
|
||||
if [ "$archDir" = "src" ]; then continue; fi
|
||||
break
|
||||
done
|
||||
echo "Found Coriolis architecture directory \"${archDir}\"."
|
||||
|
||||
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
|
||||
. ${installDir}/etc/profile.d/alc_env.sh
|
||||
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
|
||||
|
||||
export QT_X11_NO_MITSHM=1
|
|
@ -1,631 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC 2015-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s I n s t a l l e r |
|
||||
# | |
|
||||
# | Authors : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./socInstaller.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
#
|
||||
# WARNING:
|
||||
# This script has been designed only for internal use in the
|
||||
# LIP6/CIAN department. If you want to use it you will need to
|
||||
# change the hardwired configuration.
|
||||
|
||||
|
||||
showTrace = True
|
||||
|
||||
try:
|
||||
import sys
|
||||
import os.path
|
||||
import shutil
|
||||
import optparse
|
||||
import time
|
||||
import traceback
|
||||
import distutils.sysconfig
|
||||
import subprocess
|
||||
import socket
|
||||
import re
|
||||
import bz2
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.application import MIMEApplication
|
||||
except ImportError, e:
|
||||
module = str(e).split()[-1]
|
||||
|
||||
|
||||
class ErrorMessage ( Exception ):
|
||||
|
||||
def __init__ ( self, code, *arguments ):
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
if not isinstance(self._errors,list):
|
||||
return "[ERROR] %s" % self._errors
|
||||
|
||||
formatted = "\n"
|
||||
for i in range(len(self._errors)):
|
||||
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
|
||||
else: formatted += " %s" % self._errors[i]
|
||||
if i+1 < len(self._errors): formatted += "\n"
|
||||
return formatted
|
||||
|
||||
def addMessage ( self, message ):
|
||||
if not isinstance(self._errors,list):
|
||||
self._errors = [ self._errors ]
|
||||
if isinstance(message,list):
|
||||
for line in message:
|
||||
self._errors += [ line ]
|
||||
else:
|
||||
self._errors += [ message ]
|
||||
return
|
||||
|
||||
def terminate ( self ):
|
||||
print self
|
||||
sys.exit(self._code)
|
||||
|
||||
@property
|
||||
def code ( self ): return self._code
|
||||
|
||||
|
||||
class BadBinary ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, binary ):
|
||||
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
|
||||
return
|
||||
|
||||
|
||||
class BadReturnCode ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, status ):
|
||||
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
|
||||
return
|
||||
|
||||
|
||||
class Command ( object ):
|
||||
|
||||
def __init__ ( self, arguments, fdLog=None ):
|
||||
self.arguments = arguments
|
||||
self.fdLog = fdLog
|
||||
|
||||
if self.fdLog != None and not isinstance(self.fdLog,file):
|
||||
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
|
||||
return
|
||||
|
||||
def _argumentsToStr ( self, arguments ):
|
||||
s = ''
|
||||
for argument in arguments:
|
||||
if argument.find(' ') >= 0: s += ' "' + argument + '"'
|
||||
else: s += ' ' + argument
|
||||
return s
|
||||
|
||||
def log ( self, text ):
|
||||
print text[:-1]
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if isinstance(self.fdLog,file):
|
||||
self.fdLog.write( text )
|
||||
self.fdLog.flush()
|
||||
return
|
||||
|
||||
def execute ( self ):
|
||||
global conf
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
homeDir = os.environ['HOME']
|
||||
workDir = os.getcwd()
|
||||
if homeDir.startswith(homeDir):
|
||||
workDir = '~' + workDir[ len(homeDir) : ]
|
||||
user = 'root'
|
||||
if os.environ.has_key('USER'): user = os.environ['USER']
|
||||
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
|
||||
|
||||
try:
|
||||
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
|
||||
print self.arguments
|
||||
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
|
||||
self.log( line )
|
||||
except OSError, e:
|
||||
raise BadBinary( self.arguments[0] )
|
||||
|
||||
(pid,status) = os.waitpid( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
raise BadReturnCode( status )
|
||||
|
||||
return
|
||||
|
||||
|
||||
class CommandArg ( object ):
|
||||
|
||||
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
|
||||
self.command = command
|
||||
self.host = host
|
||||
self.wd = wd
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
s = ''
|
||||
if self.wd: s = 'cd %s && ' % self.wd
|
||||
|
||||
for i in range(len(self.command)):
|
||||
if i: s += ' '
|
||||
s += self.command[i]
|
||||
return s
|
||||
|
||||
def getArgs ( self ):
|
||||
if not self.host: return self.command
|
||||
return [ 'ssh', self.host, str(self) ]
|
||||
|
||||
def execute ( self ):
|
||||
if not self.host and self.wd: os.chdir( self.wd )
|
||||
Command( self.getArgs(), self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class AllianceCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, alcBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class CoriolisCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ ccbBin
|
||||
, '--root='+rootDir
|
||||
, '--project=coriolis'
|
||||
, '--make=-j%d install' % threads
|
||||
] + otherArgs
|
||||
, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class BenchsCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, benchsDir, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
|
||||
class GitRepository ( object ):
|
||||
|
||||
@staticmethod
|
||||
def getLocalRepository ( url ):
|
||||
localRepo = url.split( '/' )[-1]
|
||||
if localRepo.endswith('.git'):
|
||||
localRepo = localRepo[:-4]
|
||||
return localRepo
|
||||
|
||||
def __init__ ( self, url, cloneDir, fdLog=None ):
|
||||
self.url = url
|
||||
self.cloneDir = cloneDir
|
||||
self.localRepo = GitRepository.getLocalRepository( url )
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
@property
|
||||
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
|
||||
|
||||
def removeLocalRepo ( self ):
|
||||
if os.path.isdir(self.localRepoDir):
|
||||
print 'Removing Git local repository: <%s>' % self.localRepoDir
|
||||
shutil.rmtree( self.localRepoDir )
|
||||
return
|
||||
|
||||
def clone ( self ):
|
||||
print 'Clone/pull from:', self.url
|
||||
if not os.path.isdir(self.cloneDir):
|
||||
os.makedirs( self.cloneDir )
|
||||
|
||||
if not os.path.isdir(self.localRepoDir):
|
||||
os.chdir( self.cloneDir )
|
||||
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
|
||||
else:
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'pull' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def checkout ( self, branch ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
PrimaryNames = \
|
||||
[ 'sender' , 'receivers'
|
||||
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
|
||||
, 'homeDir' , 'masterHost'
|
||||
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
|
||||
, 'rmSource' , 'rmBuild'
|
||||
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
|
||||
, 'success' , 'rcode'
|
||||
]
|
||||
SecondaryNames = \
|
||||
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'alcBin', 'ccbBin', 'benchsDir'
|
||||
]
|
||||
|
||||
def __init__ ( self ):
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
|
||||
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
|
||||
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
|
||||
self._homeDir = os.environ['HOME']
|
||||
self._debugArg = ''
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = True
|
||||
self._doCoriolis = False
|
||||
self._doAlliance = False
|
||||
self._doBenchs = False
|
||||
self._doSendReport = False
|
||||
self._nightlyMode = False
|
||||
self._dockerMode = False
|
||||
self._chrootMode = None
|
||||
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._ccbBin = None
|
||||
self._benchsDir = None
|
||||
self._masterHost = self._detectMasterHost()
|
||||
self._success = False
|
||||
self._rcode = 0
|
||||
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute == 'masterHost' or attribute == '_masterHost':
|
||||
if value == 'lepka':
|
||||
print 'Never touch the Git tree when running on <lepka>.'
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = False
|
||||
self._doSendReport = False
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'homeDir': value = os.path.expanduser(value)
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
def _updateSecondaries ( self ):
|
||||
if self._nightlyMode:
|
||||
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
|
||||
else:
|
||||
self._rootDir = self._homeDir + '/coriolis-2.x'
|
||||
self._srcDir = self._rootDir + '/src'
|
||||
self._logDir = self._srcDir + '/logs'
|
||||
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
|
||||
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
|
||||
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
|
||||
self._masterHost = self._detectMasterHost()
|
||||
return
|
||||
|
||||
def _detectMasterHost ( self ):
|
||||
if self._chrootMode is None: return 'unknown'
|
||||
if self._chrootMode: return 'chrooted-host'
|
||||
|
||||
masterHost = 'unknown'
|
||||
hostname = socket.gethostname()
|
||||
hostAddr = socket.gethostbyname(hostname)
|
||||
|
||||
if hostname == 'lepka' and hostAddr == '127.0.0.1':
|
||||
masterHost = 'lepka'
|
||||
else:
|
||||
masterHost = hostname.split('.')[0]
|
||||
return masterHost
|
||||
|
||||
def openLog ( self, stem ):
|
||||
if not os.path.isdir(self._logDir):
|
||||
os.makedirs( self._logDir )
|
||||
|
||||
index = 0
|
||||
timeTag = time.strftime( "%Y.%m.%d" )
|
||||
while True:
|
||||
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
|
||||
if not os.path.isfile(logFile):
|
||||
print "Report log: <%s>" % logFile
|
||||
break
|
||||
index += 1
|
||||
fd = open( logFile, "w" )
|
||||
self._logs[stem] = logFile
|
||||
self._fds [stem] = fd
|
||||
return
|
||||
|
||||
def closeLogs ( self ):
|
||||
for fd in self._fds.values():
|
||||
if fd: fd.close()
|
||||
return
|
||||
|
||||
def compressLogs ( self ):
|
||||
for log in self._logs.values():
|
||||
if not log: continue
|
||||
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
|
||||
bzfd.close()
|
||||
fd.close()
|
||||
|
||||
os.unlink( log )
|
||||
return
|
||||
|
||||
def getCommands ( self, target ):
|
||||
commands = []
|
||||
|
||||
if self.doAlliance:
|
||||
if not os.path.isfile( self.alcBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.alcBin
|
||||
] )
|
||||
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
|
||||
|
||||
if self.doCoriolis:
|
||||
if not os.path.isfile( self.ccbBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
|
||||
, ' <%s>' % self.ccbBin
|
||||
] )
|
||||
|
||||
otherArgs = []
|
||||
if self.debugArg: otherArgs.append( self.debugArg )
|
||||
|
||||
if target == 'SL7_64':
|
||||
otherArgs.append( '--project=support' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'SL6_64' or target == 'SL6':
|
||||
otherArgs.append( '--project=support' )
|
||||
otherArgs.append( '--devtoolset=8' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
|
||||
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
|
||||
|
||||
if self.doBenchs:
|
||||
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
|
||||
return commands
|
||||
|
||||
|
||||
class Report ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = conf
|
||||
|
||||
commaspace = ', '
|
||||
date = time.strftime( "%A %d %B %Y" )
|
||||
stateText = 'FAILED'
|
||||
modeText = 'SoC installation'
|
||||
if self.conf.success: stateText = 'SUCCESS'
|
||||
if self.conf.nightlyMode: modeText = 'Nightly build'
|
||||
|
||||
self.message = MIMEMultipart()
|
||||
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
|
||||
self.message['From' ] = self.conf.sender
|
||||
self.message['To' ] = commaspace.join( self.conf.receivers )
|
||||
self.attachements = []
|
||||
|
||||
self.mainText = '\n'
|
||||
self.mainText += 'Salut le Crevard,\n'
|
||||
self.mainText += '\n'
|
||||
if self.conf.nightlyMode:
|
||||
self.mainText += 'This is the nightly build report of Coriolis.\n'
|
||||
else:
|
||||
self.mainText += 'SoC installer report of Coriolis.\n'
|
||||
self.mainText += '%s\n' % date
|
||||
self.mainText += '\n'
|
||||
if self.conf.success:
|
||||
self.mainText += 'Build was SUCCESSFUL\n'
|
||||
else:
|
||||
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
|
||||
self.mainText += '\n'
|
||||
self.mainText += 'Complete log file(s) can be found here:\n'
|
||||
return
|
||||
|
||||
def attachLog ( self, logFile ):
|
||||
if not logFile: return
|
||||
|
||||
fd = open( logFile, 'rb' )
|
||||
try:
|
||||
fd.seek( -1024*100, os.SEEK_END )
|
||||
except IOError, e:
|
||||
pass
|
||||
tailLines = ''
|
||||
for line in fd.readlines()[1:]:
|
||||
tailLines += line
|
||||
fd.close()
|
||||
self.mainText += ' <%s>\n' % logFile
|
||||
|
||||
attachement = MIMEApplication(tailLines)
|
||||
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
|
||||
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
|
||||
def send ( self ):
|
||||
self.message.attach( MIMEText(self.mainText) )
|
||||
for attachement in self.attachements:
|
||||
self.message.attach( attachement )
|
||||
|
||||
print "Sending mail report to:"
|
||||
for receiver in self.conf.receivers: print ' <%s>' % receiver
|
||||
session = smtplib.SMTP( 'localhost' )
|
||||
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
|
||||
session.quit()
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# <socInstaller> Main Part.
|
||||
|
||||
|
||||
parser = optparse.OptionParser ()
|
||||
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
|
||||
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
|
||||
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
|
||||
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
|
||||
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
|
||||
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
|
||||
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
|
||||
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
|
||||
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
|
||||
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
|
||||
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
|
||||
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
|
||||
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
|
||||
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
|
||||
conf = Configuration()
|
||||
|
||||
try:
|
||||
if options.debug: conf.debugArg = '--debug'
|
||||
if options.nightly: conf.nightlyMode = True
|
||||
if options.docker: conf.dockerMode = True
|
||||
if options.chroot: conf.chrootMode = True
|
||||
if options.noGit: conf.doGit = False
|
||||
if options.doCoriolis: conf.doCoriolis = True
|
||||
if options.doAlliance: conf.doAlliance = True
|
||||
if options.benchs: conf.doBenchs = True
|
||||
if options.doReport: conf.doSendReport = True
|
||||
if options.rmSource or options.rmAll: conf.rmSource = True
|
||||
if options.rmBuild or options.rmAll: conf.rmBuild = True
|
||||
|
||||
|
||||
if conf.doAlliance: conf.openLog( 'alliance' )
|
||||
if conf.doCoriolis: conf.openLog( 'coriolis' )
|
||||
if conf.doBenchs: conf.openLog( 'benchs' )
|
||||
|
||||
if conf.dockerMode: os.environ['USER'] = 'root'
|
||||
|
||||
gitSupports = []
|
||||
for supportRepo in conf.supportRepos:
|
||||
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
|
||||
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
|
||||
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
|
||||
|
||||
if conf.doAlliance:
|
||||
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
|
||||
|
||||
if conf.doGit:
|
||||
for gitSupport in gitSupports:
|
||||
if conf.rmSource: gitSupport.removeLocalRepo()
|
||||
gitSupport.clone()
|
||||
#if gitSupport.url.endswith('rapidjson'):
|
||||
# gitSupport.checkout( 'a1c4f32' )
|
||||
|
||||
if conf.doCoriolis:
|
||||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
|
||||
if conf.doAlliance:
|
||||
if conf.rmSource: gitAlliance.removeLocalRepo()
|
||||
gitAlliance.clone ()
|
||||
#gitAlliance.checkout( 'devel' )
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
|
||||
if conf.rmBuild:
|
||||
for entry in os.listdir(conf.rootDir):
|
||||
if entry.startswith('Linux.'):
|
||||
buildDir = conf.rootDir+'/'+entry
|
||||
print 'Removing OS build directory: <%s>' % buildDir
|
||||
shutil.rmtree( buildDir )
|
||||
|
||||
commands = conf.getCommands( options.profile )
|
||||
for command in commands:
|
||||
if command.host:
|
||||
print 'Executing command on remote host <%s>:' % host
|
||||
else:
|
||||
print 'Executing command on *local* host:'
|
||||
print ' %s' % str(command)
|
||||
command.execute()
|
||||
|
||||
conf.closeLogs()
|
||||
|
||||
conf.success = True
|
||||
|
||||
except ErrorMessage, e:
|
||||
print e
|
||||
conf.closeLogs()
|
||||
conf.success = False
|
||||
|
||||
if showTrace:
|
||||
print '\nPython stack trace:'
|
||||
traceback.print_tb( sys.exc_info()[2] )
|
||||
conf.rcode = e.code
|
||||
|
||||
if conf.doSendReport:
|
||||
report = Report( conf )
|
||||
report.attachLog( conf.logs['coriolis' ] )
|
||||
report.attachLog( conf.logs['benchs' ] )
|
||||
report.send()
|
||||
|
||||
conf.compressLogs()
|
||||
|
||||
sys.exit( conf.rcode )
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
FROM ubuntu18.coriolis
|
||||
|
||||
COPY root/dot.bashrc /root/.bashrc
|
||||
|
||||
CMD [ "/bin/bash", "-i" ]
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
FROM ubuntu18.system
|
||||
|
||||
COPY root/socInstaller.py /root/socInstaller.py
|
||||
RUN mkdir -p coriolis-2.x/src \
|
||||
&& git clone https://github.com/m-labs/nmigen.git \
|
||||
&& cd nmigen \
|
||||
&& python3 setup.py develop \
|
||||
&& /root/socInstaller.py --docker --profile=Ubuntu18 --do-alliance --do-coriolis
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
|
||||
FROM ubuntu:bionic
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install build-essential binutils-dev \
|
||||
git cmake bison flex gcc python-dev \
|
||||
libboost-all-dev libboost-python-dev \
|
||||
zlib1g-dev libxml2-dev rapidjson-dev libbz2-dev \
|
||||
qtbase5-dev libqt5svg5-dev libqwt-qt5-dev \
|
||||
python-pyqt5 \
|
||||
\
|
||||
autotools-dev automake \
|
||||
libxt-dev libxpm-dev libmotif-dev \
|
||||
\
|
||||
yosys \
|
||||
python3-setuptools python3-pip python3-six \
|
||||
python3-wheel \
|
||||
\
|
||||
vim \
|
||||
&& apt-get clean \
|
||||
&& pip3 install git+https://github.com/m-labs/nmigen.git
|
||||
|
||||
# For building with Qt 4 instead of Qt 5.
|
||||
# qt4-dev-tools libqwt-dev python-qt4 \
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
systemImage="ubuntu18.system"
|
||||
coriolisImage="ubuntu18.coriolis"
|
||||
bashImage="ubuntu18.bash"
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
|
||||
buildDir=${commonRoot}/build
|
||||
installDir=${commonRoot}/install
|
||||
|
||||
export ALLIANCE_TOP=${installDir}
|
||||
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
cd ${srcDir}
|
||||
# Skip doc generation to avoid pulling TeXLive in docker images.
|
||||
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
|
||||
./autostuff clean
|
||||
./autostuff
|
||||
mkdir -p ${buildDir}
|
||||
cd ${buildDir}
|
||||
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
|
||||
make -j1 install
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
echo "Running /root/.bashrc"
|
||||
|
||||
for archDir in `ls /root/coriolis-2.x/`; do
|
||||
if [ "$archDir" = "src" ]; then continue; fi
|
||||
break
|
||||
done
|
||||
echo "Found Coriolis architecture directory \"${archDir}\"."
|
||||
|
||||
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
|
||||
. ${installDir}/etc/profile.d/alc_env.sh
|
||||
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
|
||||
|
||||
export QT_X11_NO_MITSHM=1
|
|
@ -1,650 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC 2015-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s I n s t a l l e r |
|
||||
# | |
|
||||
# | Authors : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./socInstaller.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
#
|
||||
# WARNING:
|
||||
# This script has been designed only for internal use in the
|
||||
# LIP6/CIAN department. If you want to use it you will need to
|
||||
# change the hardwired configuration.
|
||||
|
||||
|
||||
showTrace = True
|
||||
|
||||
try:
|
||||
import sys
|
||||
import os.path
|
||||
import shutil
|
||||
import optparse
|
||||
import time
|
||||
import traceback
|
||||
import distutils.sysconfig
|
||||
import subprocess
|
||||
import socket
|
||||
import re
|
||||
import bz2
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.application import MIMEApplication
|
||||
except ImportError, e:
|
||||
module = str(e).split()[-1]
|
||||
|
||||
|
||||
class ErrorMessage ( Exception ):
|
||||
|
||||
def __init__ ( self, code, *arguments ):
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
if not isinstance(self._errors,list):
|
||||
return "[ERROR] %s" % self._errors
|
||||
|
||||
formatted = "\n"
|
||||
for i in range(len(self._errors)):
|
||||
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
|
||||
else: formatted += " %s" % self._errors[i]
|
||||
if i+1 < len(self._errors): formatted += "\n"
|
||||
return formatted
|
||||
|
||||
def addMessage ( self, message ):
|
||||
if not isinstance(self._errors,list):
|
||||
self._errors = [ self._errors ]
|
||||
if isinstance(message,list):
|
||||
for line in message:
|
||||
self._errors += [ line ]
|
||||
else:
|
||||
self._errors += [ message ]
|
||||
return
|
||||
|
||||
def terminate ( self ):
|
||||
print self
|
||||
sys.exit(self._code)
|
||||
|
||||
@property
|
||||
def code ( self ): return self._code
|
||||
|
||||
|
||||
class BadBinary ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, binary ):
|
||||
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
|
||||
return
|
||||
|
||||
|
||||
class BadReturnCode ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, status ):
|
||||
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
|
||||
return
|
||||
|
||||
|
||||
class Command ( object ):
|
||||
|
||||
def __init__ ( self, arguments, fdLog=None ):
|
||||
self.arguments = arguments
|
||||
self.fdLog = fdLog
|
||||
|
||||
if self.fdLog != None and not isinstance(self.fdLog,file):
|
||||
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
|
||||
return
|
||||
|
||||
def _argumentsToStr ( self, arguments ):
|
||||
s = ''
|
||||
for argument in arguments:
|
||||
if argument.find(' ') >= 0: s += ' "' + argument + '"'
|
||||
else: s += ' ' + argument
|
||||
return s
|
||||
|
||||
def log ( self, text ):
|
||||
print text[:-1]
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if isinstance(self.fdLog,file):
|
||||
self.fdLog.write( text )
|
||||
self.fdLog.flush()
|
||||
return
|
||||
|
||||
def execute ( self ):
|
||||
global conf
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
homeDir = os.environ['HOME']
|
||||
workDir = os.getcwd()
|
||||
if homeDir.startswith(homeDir):
|
||||
workDir = '~' + workDir[ len(homeDir) : ]
|
||||
user = 'root'
|
||||
if os.environ.has_key('USER'): user = os.environ['USER']
|
||||
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
|
||||
|
||||
try:
|
||||
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
|
||||
print self.arguments
|
||||
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
|
||||
self.log( line )
|
||||
except OSError, e:
|
||||
raise BadBinary( self.arguments[0] )
|
||||
|
||||
(pid,status) = os.waitpid( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
raise BadReturnCode( status )
|
||||
|
||||
return
|
||||
|
||||
|
||||
class CommandArg ( object ):
|
||||
|
||||
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
|
||||
self.command = command
|
||||
self.host = host
|
||||
self.wd = wd
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
s = ''
|
||||
if self.wd: s = 'cd %s && ' % self.wd
|
||||
|
||||
for i in range(len(self.command)):
|
||||
if i: s += ' '
|
||||
s += self.command[i]
|
||||
return s
|
||||
|
||||
def getArgs ( self ):
|
||||
if not self.host: return self.command
|
||||
return [ 'ssh', self.host, str(self) ]
|
||||
|
||||
def execute ( self ):
|
||||
if not self.host and self.wd: os.chdir( self.wd )
|
||||
Command( self.getArgs(), self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class YosysCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, yosysBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ yosysBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class AllianceCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, alcBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class CoriolisCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ ccbBin
|
||||
, '--root='+rootDir
|
||||
, '--project=coriolis'
|
||||
, '--make=-j%d install' % threads
|
||||
] + otherArgs
|
||||
, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class BenchsCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, benchsDir, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
|
||||
class GitRepository ( object ):
|
||||
|
||||
@staticmethod
|
||||
def getLocalRepository ( url ):
|
||||
localRepo = url.split( '/' )[-1]
|
||||
if localRepo.endswith('.git'):
|
||||
localRepo = localRepo[:-4]
|
||||
return localRepo
|
||||
|
||||
def __init__ ( self, url, cloneDir, fdLog=None ):
|
||||
self.url = url
|
||||
self.cloneDir = cloneDir
|
||||
self.localRepo = GitRepository.getLocalRepository( url )
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
@property
|
||||
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
|
||||
|
||||
def removeLocalRepo ( self ):
|
||||
if os.path.isdir(self.localRepoDir):
|
||||
print 'Removing Git local repository: <%s>' % self.localRepoDir
|
||||
shutil.rmtree( self.localRepoDir )
|
||||
return
|
||||
|
||||
def clone ( self ):
|
||||
print 'Clone/pull from:', self.url
|
||||
if not os.path.isdir(self.cloneDir):
|
||||
os.makedirs( self.cloneDir )
|
||||
|
||||
if not os.path.isdir(self.localRepoDir):
|
||||
os.chdir( self.cloneDir )
|
||||
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
|
||||
else:
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'pull' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def checkout ( self, branch ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
PrimaryNames = \
|
||||
[ 'sender' , 'receivers'
|
||||
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
|
||||
, 'homeDir' , 'masterHost'
|
||||
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
|
||||
, 'rmSource' , 'rmBuild'
|
||||
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
|
||||
, 'success' , 'rcode'
|
||||
]
|
||||
SecondaryNames = \
|
||||
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'yosysBin', 'alcBin', 'ccbBin', 'benchsDir'
|
||||
]
|
||||
|
||||
def __init__ ( self ):
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
|
||||
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
|
||||
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
|
||||
self._homeDir = os.environ['HOME']
|
||||
self._debugArg = ''
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = True
|
||||
self._doYosys = False
|
||||
self._doAlliance = False
|
||||
self._doCoriolis = False
|
||||
self._doBenchs = False
|
||||
self._doSendReport = False
|
||||
self._nightlyMode = False
|
||||
self._dockerMode = False
|
||||
self._chrootMode = None
|
||||
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._ccbBin = None
|
||||
self._benchsDir = None
|
||||
self._masterHost = self._detectMasterHost()
|
||||
self._success = False
|
||||
self._rcode = 0
|
||||
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute == 'masterHost' or attribute == '_masterHost':
|
||||
if value == 'lepka':
|
||||
print 'Never touch the Git tree when running on <lepka>.'
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = False
|
||||
self._doSendReport = False
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'homeDir': value = os.path.expanduser(value)
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
def _updateSecondaries ( self ):
|
||||
if self._nightlyMode:
|
||||
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
|
||||
else:
|
||||
self._rootDir = self._homeDir + '/coriolis-2.x'
|
||||
self._srcDir = self._rootDir + '/src'
|
||||
self._logDir = self._srcDir + '/logs'
|
||||
self._yosysBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/yosysInstaller.sh'
|
||||
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
|
||||
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
|
||||
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
|
||||
self._masterHost = self._detectMasterHost()
|
||||
return
|
||||
|
||||
def _detectMasterHost ( self ):
|
||||
if self._chrootMode is None: return 'unknown'
|
||||
if self._chrootMode: return 'chrooted-host'
|
||||
|
||||
masterHost = 'unknown'
|
||||
hostname = socket.gethostname()
|
||||
hostAddr = socket.gethostbyname(hostname)
|
||||
|
||||
if hostname == 'lepka' and hostAddr == '127.0.0.1':
|
||||
masterHost = 'lepka'
|
||||
else:
|
||||
masterHost = hostname.split('.')[0]
|
||||
return masterHost
|
||||
|
||||
def openLog ( self, stem ):
|
||||
if not os.path.isdir(self._logDir):
|
||||
os.makedirs( self._logDir )
|
||||
|
||||
index = 0
|
||||
timeTag = time.strftime( "%Y.%m.%d" )
|
||||
while True:
|
||||
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
|
||||
if not os.path.isfile(logFile):
|
||||
print "Report log: <%s>" % logFile
|
||||
break
|
||||
index += 1
|
||||
fd = open( logFile, "w" )
|
||||
self._logs[stem] = logFile
|
||||
self._fds [stem] = fd
|
||||
return
|
||||
|
||||
def closeLogs ( self ):
|
||||
for fd in self._fds.values():
|
||||
if fd: fd.close()
|
||||
return
|
||||
|
||||
def compressLogs ( self ):
|
||||
for log in self._logs.values():
|
||||
if not log: continue
|
||||
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
|
||||
bzfd.close()
|
||||
fd.close()
|
||||
|
||||
os.unlink( log )
|
||||
return
|
||||
|
||||
def getCommands ( self, target ):
|
||||
commands = []
|
||||
|
||||
if self.doYosys:
|
||||
if not os.path.isfile( self.yosysBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <yosysInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.yosysBin
|
||||
] )
|
||||
commands.append( YosysCommand( self.yosysBin, fdLog=self.fds['yosys'] ) )
|
||||
|
||||
if self.doAlliance:
|
||||
if not os.path.isfile( self.alcBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.alcBin
|
||||
] )
|
||||
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
|
||||
|
||||
if self.doCoriolis:
|
||||
if not os.path.isfile( self.ccbBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
|
||||
, ' <%s>' % self.ccbBin
|
||||
] )
|
||||
|
||||
otherArgs = []
|
||||
if self.debugArg: otherArgs.append( self.debugArg )
|
||||
|
||||
if target == 'SL7_64':
|
||||
otherArgs.append( '--project=support' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'SL6_64' or target == 'SL6':
|
||||
otherArgs.append( '--project=support' )
|
||||
otherArgs.append( '--devtoolset=8' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
|
||||
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
|
||||
|
||||
if self.doBenchs:
|
||||
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
|
||||
return commands
|
||||
|
||||
|
||||
class Report ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = conf
|
||||
|
||||
commaspace = ', '
|
||||
date = time.strftime( "%A %d %B %Y" )
|
||||
stateText = 'FAILED'
|
||||
modeText = 'SoC installation'
|
||||
if self.conf.success: stateText = 'SUCCESS'
|
||||
if self.conf.nightlyMode: modeText = 'Nightly build'
|
||||
|
||||
self.message = MIMEMultipart()
|
||||
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
|
||||
self.message['From' ] = self.conf.sender
|
||||
self.message['To' ] = commaspace.join( self.conf.receivers )
|
||||
self.attachements = []
|
||||
|
||||
self.mainText = '\n'
|
||||
self.mainText += 'Salut le Crevard,\n'
|
||||
self.mainText += '\n'
|
||||
if self.conf.nightlyMode:
|
||||
self.mainText += 'This is the nightly build report of Coriolis.\n'
|
||||
else:
|
||||
self.mainText += 'SoC installer report of Coriolis.\n'
|
||||
self.mainText += '%s\n' % date
|
||||
self.mainText += '\n'
|
||||
if self.conf.success:
|
||||
self.mainText += 'Build was SUCCESSFUL\n'
|
||||
else:
|
||||
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
|
||||
self.mainText += '\n'
|
||||
self.mainText += 'Complete log file(s) can be found here:\n'
|
||||
return
|
||||
|
||||
def attachLog ( self, logFile ):
|
||||
if not logFile: return
|
||||
|
||||
fd = open( logFile, 'rb' )
|
||||
try:
|
||||
fd.seek( -1024*100, os.SEEK_END )
|
||||
except IOError, e:
|
||||
pass
|
||||
tailLines = ''
|
||||
for line in fd.readlines()[1:]:
|
||||
tailLines += line
|
||||
fd.close()
|
||||
self.mainText += ' <%s>\n' % logFile
|
||||
|
||||
attachement = MIMEApplication(tailLines)
|
||||
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
|
||||
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
|
||||
def send ( self ):
|
||||
self.message.attach( MIMEText(self.mainText) )
|
||||
for attachement in self.attachements:
|
||||
self.message.attach( attachement )
|
||||
|
||||
print "Sending mail report to:"
|
||||
for receiver in self.conf.receivers: print ' <%s>' % receiver
|
||||
session = smtplib.SMTP( 'localhost' )
|
||||
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
|
||||
session.quit()
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# <socInstaller> Main Part.
|
||||
|
||||
|
||||
parser = optparse.OptionParser ()
|
||||
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
|
||||
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
|
||||
parser.add_option ( "--do-yosys" , action="store_true" , dest="doYosys" , help="Rebuild Yosys." )
|
||||
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
|
||||
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
|
||||
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
|
||||
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
|
||||
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
|
||||
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
|
||||
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
|
||||
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
|
||||
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
|
||||
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
|
||||
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
|
||||
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
|
||||
conf = Configuration()
|
||||
|
||||
try:
|
||||
if options.debug: conf.debugArg = '--debug'
|
||||
if options.nightly: conf.nightlyMode = True
|
||||
if options.docker: conf.dockerMode = True
|
||||
if options.chroot: conf.chrootMode = True
|
||||
if options.noGit: conf.doGit = False
|
||||
if options.doYosys: conf.doYosys = True
|
||||
if options.doAlliance: conf.doAlliance = True
|
||||
if options.doCoriolis: conf.doCoriolis = True
|
||||
if options.benchs: conf.doBenchs = True
|
||||
if options.doReport: conf.doSendReport = True
|
||||
if options.rmSource or options.rmAll: conf.rmSource = True
|
||||
if options.rmBuild or options.rmAll: conf.rmBuild = True
|
||||
|
||||
|
||||
if conf.doYosys: conf.openLog( 'yosys' )
|
||||
if conf.doAlliance: conf.openLog( 'alliance' )
|
||||
if conf.doCoriolis: conf.openLog( 'coriolis' )
|
||||
if conf.doBenchs: conf.openLog( 'benchs' )
|
||||
|
||||
if conf.dockerMode: os.environ['USER'] = 'root'
|
||||
|
||||
gitSupports = []
|
||||
for supportRepo in conf.supportRepos:
|
||||
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
|
||||
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
|
||||
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
|
||||
|
||||
if conf.doAlliance:
|
||||
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
|
||||
|
||||
if conf.doGit:
|
||||
for gitSupport in gitSupports:
|
||||
if conf.rmSource: gitSupport.removeLocalRepo()
|
||||
gitSupport.clone()
|
||||
#if gitSupport.url.endswith('rapidjson'):
|
||||
# gitSupport.checkout( 'a1c4f32' )
|
||||
|
||||
if conf.doAlliance:
|
||||
if conf.rmSource: gitAlliance.removeLocalRepo()
|
||||
gitAlliance.clone ()
|
||||
#gitAlliance.checkout( 'devel' )
|
||||
|
||||
if conf.doCoriolis:
|
||||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
|
||||
if conf.rmBuild:
|
||||
for entry in os.listdir(conf.rootDir):
|
||||
if entry.startswith('Linux.'):
|
||||
buildDir = conf.rootDir+'/'+entry
|
||||
print 'Removing OS build directory: <%s>' % buildDir
|
||||
shutil.rmtree( buildDir )
|
||||
|
||||
commands = conf.getCommands( options.profile )
|
||||
for command in commands:
|
||||
if command.host:
|
||||
print 'Executing command on remote host <%s>:' % host
|
||||
else:
|
||||
print 'Executing command on *local* host:'
|
||||
print ' %s' % str(command)
|
||||
command.execute()
|
||||
|
||||
conf.closeLogs()
|
||||
|
||||
conf.success = True
|
||||
|
||||
except ErrorMessage, e:
|
||||
print e
|
||||
conf.closeLogs()
|
||||
conf.success = False
|
||||
|
||||
if showTrace:
|
||||
print '\nPython stack trace:'
|
||||
traceback.print_tb( sys.exc_info()[2] )
|
||||
conf.rcode = e.code
|
||||
|
||||
if conf.doSendReport:
|
||||
report = Report( conf )
|
||||
report.attachLog( conf.logs['coriolis' ] )
|
||||
report.attachLog( conf.logs['benchs' ] )
|
||||
report.send()
|
||||
|
||||
conf.compressLogs()
|
||||
|
||||
sys.exit( conf.rcode )
|
|
@ -1,133 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
showHelp=0
|
||||
showError=0
|
||||
doBuildSystem=0
|
||||
doBuildCoriolis=0
|
||||
doBuildBash=0
|
||||
doBuild=0
|
||||
doRun=0
|
||||
doRemove=0
|
||||
|
||||
|
||||
if [ ! -f "./docker-conf.sh" ]; then
|
||||
echo "[ERROR] Missing \"./docker-conf.sh\"."
|
||||
echo " (wd:\"`pwd`\")"
|
||||
exit 1
|
||||
fi
|
||||
. "./docker-conf.sh"
|
||||
dockerImages="${systemImage},${coriolisImage},${bashImage}"
|
||||
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--help) showHelp=1;;
|
||||
--build-system) doBuildSystem=1;;
|
||||
--build-coriolis) doBuildCoriolis=1;;
|
||||
--build-bash) doBuildBash=1;;
|
||||
--run) doRun=1;;
|
||||
--remove) doRemove=1;;
|
||||
-*) NB=2; CH=`echo $1 | cut -c$NB`
|
||||
while [ "$CH" != "" ]; do
|
||||
case $CH in
|
||||
h) showHelp=1;;
|
||||
s) doBuildSystem=1;;
|
||||
c) doBuildCoriolis=1;;
|
||||
b) doBuildBash=1;;
|
||||
r) doRun=1;;
|
||||
*) showError=1; badOption="$1";;
|
||||
esac
|
||||
NB=`expr $NB + 1`
|
||||
CH=`echo $1 | cut -c$NB`
|
||||
done;;
|
||||
*) showError=1; badOption="$1";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ ${showError} -ne 0 ]; then
|
||||
echo "[ERROR] Unknown argument \"${badOption}\"."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${showHelp} -ne 0 ]; then
|
||||
echo "Usage: ./manager.sh [options]"
|
||||
echo "Options:"
|
||||
echo " * [-h|--help]: Print this help."
|
||||
echo " * [-s|--build-system]: Rebuild the whole OS image."
|
||||
echo " * [-c|--build-coriolis]: Rebuild the Coriolis image. It will remove the previous"
|
||||
echo " images (${dockerImages})."
|
||||
echo " * [-b|--build-bash]: Rebuild the Bash (shell) image. It will remove the previous"
|
||||
echo " image (${bashImage})."
|
||||
echo " * [-r|--run]: Recompile Alliance, Coriolis & perform benchs."
|
||||
echo " * [--remove]: Remove container(s) & image(s)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
if [ ${doBuildSystem} -ne 0 ]; then
|
||||
doBuildBash=1
|
||||
doBuildCoriolis=1
|
||||
doBuild=1
|
||||
doRemove=1
|
||||
fi
|
||||
|
||||
if [ ${doBuildCoriolis} -ne 0 ]; then
|
||||
doBuildBash=1
|
||||
doBuild=1
|
||||
doRemove=1
|
||||
fi
|
||||
|
||||
if [ ${doBuildBash} -ne 0 ]; then
|
||||
doBuild=1
|
||||
doRemove=1
|
||||
fi
|
||||
|
||||
|
||||
if [ ${doRemove} -ne 0 ]; then
|
||||
if [ ${doBuildBash} -ne 0 ]; then
|
||||
echo "Removing \"${bashImage}\" docker container."
|
||||
docker rm ${bashImage}
|
||||
docker rmi ${bashImage}
|
||||
fi
|
||||
|
||||
if [ ${doBuildCoriolis} -ne 0 ]; then
|
||||
echo "Removing \"${coriolisImage}\" docker image."
|
||||
docker rm ${coriolisImage}
|
||||
docker rmi ${coriolisImage}
|
||||
fi
|
||||
|
||||
if [ ${doBuildSystem} -ne 0 ]; then
|
||||
echo "Removing \"${systemImage}\" docker image."
|
||||
docker rm ${systemImage}
|
||||
docker rmi ${systemImage}
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ ${doBuild} -ne 0 ]; then
|
||||
echo "Synching Alliance & Coriolis builder scripts."
|
||||
cp ../../socInstaller.py ./root
|
||||
cp ../../dot.bashrc ./root
|
||||
|
||||
if [ ${doBuildSystem} -ne 0 ]; then
|
||||
echo "Build \"${systemImage}\" docker image."
|
||||
docker build -f Dockerfile.system -t ${systemImage} .
|
||||
fi
|
||||
|
||||
if [ ${doBuildCoriolis} -ne 0 ]; then
|
||||
echo "Build \"${coriolisImage}\" docker image."
|
||||
docker build -f Dockerfile.coriolis -t ${coriolisImage} .
|
||||
fi
|
||||
|
||||
if [ ${doBuildBash} -ne 0 ]; then
|
||||
echo "Build \"${bashImage}\" docker image."
|
||||
docker build -f Dockerfile.bash -t ${bashImage} .
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ ${doRun} -ne 0 ]; then
|
||||
docker run --rm --net=host -e DISPLAY=:0 -ti --name ${bashImage} ${bashImage}
|
||||
fi
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
echo "Running /root/.bashrc"
|
||||
|
||||
for archDir in `ls /root/coriolis-2.x/`; do
|
||||
if [ "$archDir" = "src" ]; then continue; fi
|
||||
break
|
||||
done
|
||||
echo "Found Coriolis architecture directory \"${archDir}\"."
|
||||
|
||||
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
|
||||
. ${installDir}/etc/profile.d/alc_env.sh
|
||||
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
|
||||
|
||||
export QT_X11_NO_MITSHM=1
|
|
@ -1,31 +0,0 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
docDirs=""
|
||||
docDirs="${docDirs} hurricane/doc/analog"
|
||||
docDirs="${docDirs} hurricane/doc/hurricane"
|
||||
docDirs="${docDirs} hurricane/doc/viewer"
|
||||
docDirs="${docDirs} crlcore/doc/crlcore"
|
||||
docDirs="${docDirs} katabatic/doc"
|
||||
docDirs="${docDirs} kite/doc"
|
||||
docDirs="${docDirs} oroshi/doc"
|
||||
docDirs="${docDirs} unicorn/doc/unicorn"
|
||||
docDirs="${docDirs} vlsisapd/doc"
|
||||
docDirs="${docDirs} vlsisapd/doc"
|
||||
|
||||
resetDir ()
|
||||
{
|
||||
directory="$1"
|
||||
echo "Resetting \"${directory} ..."
|
||||
if [ -d "${directory}" ]; then
|
||||
rm -rf "${directory}"
|
||||
git checkout "${directory}"
|
||||
fi
|
||||
}
|
||||
|
||||
for docDir in ${docDirs}; do
|
||||
resetDir "${docDir}/html"
|
||||
resetDir "${docDir}/latex"
|
||||
resetDir "${docDir}/man"
|
||||
resetDir "${docDir}/rtf"
|
||||
done
|
||||
resetDir "documentation/output/pdfs"
|
|
@ -46,31 +46,31 @@ except ImportError, e:
|
|||
class ErrorMessage ( Exception ):
|
||||
|
||||
def __init__ ( self, code, *arguments ):
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
if not isinstance(self._errors,list):
|
||||
|
@ -104,433 +104,321 @@ class ErrorMessage ( Exception ):
|
|||
class BadBinary ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, binary ):
|
||||
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
|
||||
return
|
||||
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
|
||||
return
|
||||
|
||||
|
||||
class BadReturnCode ( ErrorMessage ):
|
||||
|
||||
def __init__ ( self, status ):
|
||||
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
|
||||
return
|
||||
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
|
||||
return
|
||||
|
||||
|
||||
class Command ( object ):
|
||||
|
||||
def __init__ ( self, arguments, fdLog=None ):
|
||||
self.arguments = arguments
|
||||
self.fdLog = fdLog
|
||||
|
||||
if self.fdLog != None and not isinstance(self.fdLog,file):
|
||||
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
|
||||
return
|
||||
self.arguments = arguments
|
||||
self.fdLog = fdLog
|
||||
|
||||
if self.fdLog != None and not isinstance(self.fdLog,file):
|
||||
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
|
||||
return
|
||||
|
||||
def _argumentsToStr ( self, arguments ):
|
||||
s = ''
|
||||
for argument in arguments:
|
||||
if argument.find(' ') >= 0: s += ' "' + argument + '"'
|
||||
else: s += ' ' + argument
|
||||
return s
|
||||
s = ''
|
||||
for argument in arguments:
|
||||
if argument.find(' ') >= 0: s += ' "' + argument + '"'
|
||||
else: s += ' ' + argument
|
||||
return s
|
||||
|
||||
def log ( self, text ):
|
||||
print text[:-1]
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if isinstance(self.fdLog,file):
|
||||
self.fdLog.write( text )
|
||||
self.fdLog.flush()
|
||||
return
|
||||
print text[:-1]
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if isinstance(self.fdLog,file):
|
||||
self.fdLog.write( text )
|
||||
self.fdLog.flush()
|
||||
return
|
||||
|
||||
def execute ( self ):
|
||||
global conf
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
homeDir = os.environ['HOME']
|
||||
workDir = os.getcwd()
|
||||
if homeDir.startswith(homeDir):
|
||||
workDir = '~' + workDir[ len(homeDir) : ]
|
||||
user = 'root'
|
||||
if os.environ.has_key('USER'): user = os.environ['USER']
|
||||
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
|
||||
|
||||
try:
|
||||
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
|
||||
print self.arguments
|
||||
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
|
||||
self.log( line )
|
||||
except OSError, e:
|
||||
raise BadBinary( self.arguments[0] )
|
||||
|
||||
(pid,status) = os.waitpid( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
raise BadReturnCode( status )
|
||||
|
||||
return
|
||||
global conf
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
homeDir = os.environ['HOME']
|
||||
workDir = os.getcwd()
|
||||
if homeDir.startswith(homeDir):
|
||||
workDir = '~' + workDir[ len(homeDir) : ]
|
||||
prompt = '%s@%s:%s$' % (os.environ['USER'],conf.masterHost,workDir)
|
||||
|
||||
class CommandArg ( object ):
|
||||
try:
|
||||
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
|
||||
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
|
||||
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
|
||||
self.command = command
|
||||
self.host = host
|
||||
self.wd = wd
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
|
||||
def __str__ ( self ):
|
||||
s = ''
|
||||
if self.wd: s = 'cd %s && ' % self.wd
|
||||
self.log( line )
|
||||
except OSError, e:
|
||||
raise BadBinary( self.arguments[0] )
|
||||
|
||||
for i in range(len(self.command)):
|
||||
if i: s += ' '
|
||||
s += self.command[i]
|
||||
return s
|
||||
(pid,status) = os.waitpid( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
raise BadReturnCode( status )
|
||||
|
||||
def getArgs ( self ):
|
||||
if not self.host: return self.command
|
||||
return [ 'ssh', self.host, str(self) ]
|
||||
|
||||
def execute ( self ):
|
||||
if not self.host and self.wd: os.chdir( self.wd )
|
||||
Command( self.getArgs(), self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class YosysCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, yosysBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ yosysBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class AllianceCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, alcBin, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class CoriolisCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ ccbBin
|
||||
, '--root='+rootDir
|
||||
, '--project=coriolis'
|
||||
, '--make=-j%d install' % threads
|
||||
] + otherArgs
|
||||
, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
class BenchsCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, benchsDir, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
|
||||
class GitRepository ( object ):
|
||||
|
||||
@staticmethod
|
||||
def getLocalRepository ( url ):
|
||||
localRepo = url.split( '/' )[-1]
|
||||
if localRepo.endswith('.git'):
|
||||
localRepo = localRepo[:-4]
|
||||
return localRepo
|
||||
localRepo = url.split( '/' )[-1]
|
||||
if localRepo.endswith('.git'):
|
||||
localRepo = localRepo[:-4]
|
||||
return localRepo
|
||||
|
||||
def __init__ ( self, url, cloneDir, fdLog=None ):
|
||||
self.url = url
|
||||
self.cloneDir = cloneDir
|
||||
self.localRepo = GitRepository.getLocalRepository( url )
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
self.url = url
|
||||
self.cloneDir = cloneDir
|
||||
self.localRepo = GitRepository.getLocalRepository( url )
|
||||
self.fdLog = fdLog
|
||||
return
|
||||
|
||||
@property
|
||||
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
|
||||
|
||||
def removeLocalRepo ( self ):
|
||||
if os.path.isdir(self.localRepoDir):
|
||||
print 'Removing Git local repository: <%s>' % self.localRepoDir
|
||||
shutil.rmtree( self.localRepoDir )
|
||||
return
|
||||
if os.path.isdir(self.localRepoDir):
|
||||
print 'Removing Git local repository: <%s>' % self.localRepoDir
|
||||
shutil.rmtree( self.localRepoDir )
|
||||
return
|
||||
|
||||
def clone ( self ):
|
||||
print 'Clone/pull from:', self.url
|
||||
if not os.path.isdir(self.cloneDir):
|
||||
os.makedirs( self.cloneDir )
|
||||
|
||||
if not os.path.isdir(self.localRepoDir):
|
||||
os.chdir( self.cloneDir )
|
||||
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
|
||||
else:
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'pull' ], self.fdLog ).execute()
|
||||
return
|
||||
print 'Clone/pull from:', self.url
|
||||
if not os.path.isdir(self.cloneDir):
|
||||
os.makedirs( self.cloneDir )
|
||||
|
||||
if not os.path.isdir(self.localRepoDir):
|
||||
os.chdir( self.cloneDir )
|
||||
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
|
||||
else:
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'pull' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def checkout ( self, branch ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
PrimaryNames = \
|
||||
[ 'sender' , 'receivers'
|
||||
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
|
||||
, 'coriolisRepo', 'benchsRepo', 'supportRepos'
|
||||
, 'homeDir' , 'masterHost'
|
||||
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
|
||||
, 'rmSource' , 'rmBuild'
|
||||
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
|
||||
, 'debugArg' , 'nightlyMode'
|
||||
, 'rmSource' , 'rmBuild', 'doGit', 'doBuild', 'doBenchs', 'doSendReport'
|
||||
, 'success' , 'rcode'
|
||||
]
|
||||
SecondaryNames = \
|
||||
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'yosysBin', 'alcBin', 'ccbBin', 'benchsDir'
|
||||
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds'
|
||||
]
|
||||
|
||||
def __init__ ( self ):
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
|
||||
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
|
||||
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
|
||||
self._homeDir = os.environ['HOME']
|
||||
self._debugArg = ''
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = True
|
||||
self._doYosys = False
|
||||
self._doAlliance = False
|
||||
self._doCoriolis = False
|
||||
self._doBenchs = False
|
||||
self._doSendReport = False
|
||||
self._nightlyMode = False
|
||||
self._dockerMode = False
|
||||
self._chrootMode = None
|
||||
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
|
||||
self._ccbBin = None
|
||||
self._benchsDir = None
|
||||
self._masterHost = self._detectMasterHost()
|
||||
self._success = False
|
||||
self._rcode = 0
|
||||
|
||||
self._updateSecondaries()
|
||||
return
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._coriolisRepo = 'https://www-soc.lip6.fr/git/coriolis.git'
|
||||
self._benchsRepo = 'https://www-soc.lip6.fr/git/alliance-check-toolkit.git'
|
||||
self._homeDir = os.environ['HOME']
|
||||
self._debugArg = ''
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = True
|
||||
self._doBuild = True
|
||||
self._doBenchs = False
|
||||
self._doSendReport = True
|
||||
self._nightlyMode = False
|
||||
self._logs = { 'build':None, 'benchs':None }
|
||||
self._fds = { 'build':None, 'benchs':None }
|
||||
self._masterHost = self._detectMasterHost()
|
||||
self._success = False
|
||||
self._rcode = 0
|
||||
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute == 'masterHost' or attribute == '_masterHost':
|
||||
if value == 'lepka':
|
||||
print 'Never touch the Git tree when running on <lepka>.'
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = False
|
||||
self._doSendReport = False
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'homeDir': value = os.path.expanduser(value)
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondaries()
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute == 'masterHost' or attribute == '_masterHost':
|
||||
if value == 'lepka':
|
||||
print 'Never touch the Git tree when running on <lepka>.'
|
||||
self._rmSource = False
|
||||
self._rmBuild = False
|
||||
self._doGit = False
|
||||
self._doSendReport = False
|
||||
self._targets = { 'SL6' :None
|
||||
, 'SL6_64':None
|
||||
, 'SL7_64':'lepka'
|
||||
}
|
||||
else:
|
||||
self._targets = { 'SL6' :None
|
||||
, 'SL6_64':None
|
||||
, 'SL7_64':'bop'
|
||||
}
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'homeDir': value = os.path.expanduser(value)
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondaries()
|
||||
return
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
def _updateSecondaries ( self ):
|
||||
if self._nightlyMode:
|
||||
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
|
||||
else:
|
||||
self._rootDir = self._homeDir + '/coriolis-2.x'
|
||||
self._srcDir = self._rootDir + '/src'
|
||||
self._logDir = self._srcDir + '/logs'
|
||||
self._yosysBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/yosysInstaller.sh'
|
||||
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
|
||||
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
|
||||
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
|
||||
self._masterHost = self._detectMasterHost()
|
||||
return
|
||||
if self._nightlyMode:
|
||||
self._targets['SL6'] = None
|
||||
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
|
||||
else:
|
||||
if self._masterHost != 'lepka':
|
||||
self._targets['SL6'] = None
|
||||
self._rootDir = self._homeDir + '/coriolis-2.x'
|
||||
self._srcDir = self._rootDir + '/src'
|
||||
self._logDir = self._srcDir + '/logs'
|
||||
return
|
||||
|
||||
def _detectMasterHost ( self ):
|
||||
if self._chrootMode is None: return 'unknown'
|
||||
if self._chrootMode: return 'chrooted-host'
|
||||
|
||||
masterHost = 'unknown'
|
||||
hostname = socket.gethostname()
|
||||
hostAddr = socket.gethostbyname(hostname)
|
||||
|
||||
if hostname == 'lepka' and hostAddr == '127.0.0.1':
|
||||
masterHost = 'lepka'
|
||||
else:
|
||||
masterHost = hostname.split('.')[0]
|
||||
return masterHost
|
||||
masterHost = 'unknown'
|
||||
hostname = socket.gethostname()
|
||||
hostAddr = socket.gethostbyname(hostname)
|
||||
|
||||
if hostname == 'lepka' and hostAddr == '127.0.0.1':
|
||||
masterHost = 'lepka'
|
||||
else:
|
||||
masterHost = hostname.split('.')[0]
|
||||
return masterHost
|
||||
|
||||
def openLog ( self, stem ):
|
||||
if not os.path.isdir(self._logDir):
|
||||
os.makedirs( self._logDir )
|
||||
|
||||
index = 0
|
||||
timeTag = time.strftime( "%Y.%m.%d" )
|
||||
while True:
|
||||
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
|
||||
if not os.path.isfile(logFile):
|
||||
print "Report log: <%s>" % logFile
|
||||
break
|
||||
index += 1
|
||||
fd = open( logFile, "w" )
|
||||
self._logs[stem] = logFile
|
||||
self._fds [stem] = fd
|
||||
return
|
||||
if not os.path.isdir(self._logDir):
|
||||
os.makedirs( self._logDir )
|
||||
|
||||
index = 0
|
||||
timeTag = time.strftime( "%Y.%m.%d" )
|
||||
while True:
|
||||
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
|
||||
if not os.path.isfile(logFile):
|
||||
print "Report log: <%s>" % logFile
|
||||
break
|
||||
index += 1
|
||||
fd = open( logFile, "w" )
|
||||
self._logs[stem] = logFile
|
||||
self._fds [stem] = fd
|
||||
return
|
||||
|
||||
def closeLogs ( self ):
|
||||
for fd in self._fds.values():
|
||||
if fd: fd.close()
|
||||
return
|
||||
for fd in self._fds.values():
|
||||
if fd: fd.close()
|
||||
return
|
||||
|
||||
def compressLogs ( self ):
|
||||
for log in self._logs.values():
|
||||
if not log: continue
|
||||
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
|
||||
bzfd.close()
|
||||
fd.close()
|
||||
|
||||
os.unlink( log )
|
||||
return
|
||||
for log in self._logs.values():
|
||||
if not log: continue
|
||||
|
||||
def getCommands ( self, target ):
|
||||
commands = []
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
|
||||
if self.doYosys:
|
||||
if not os.path.isfile( self.yosysBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <yosysInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.yosysBin
|
||||
] )
|
||||
commands.append( YosysCommand( self.yosysBin, fdLog=self.fds['yosys'] ) )
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
|
||||
if self.doAlliance:
|
||||
if not os.path.isfile( self.alcBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
|
||||
, ' <%s>' % self.alcBin
|
||||
] )
|
||||
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
|
||||
bzfd.close()
|
||||
fd.close()
|
||||
|
||||
if self.doCoriolis:
|
||||
if not os.path.isfile( self.ccbBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
|
||||
, ' <%s>' % self.ccbBin
|
||||
] )
|
||||
|
||||
otherArgs = []
|
||||
if self.debugArg: otherArgs.append( self.debugArg )
|
||||
|
||||
if target == 'SL7_64':
|
||||
otherArgs.append( '--project=support' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'SL6_64' or target == 'SL6':
|
||||
otherArgs.append( '--project=support' )
|
||||
otherArgs.append( '--devtoolset=8' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
|
||||
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
|
||||
|
||||
if self.doBenchs:
|
||||
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
|
||||
return commands
|
||||
os.unlink( log )
|
||||
return
|
||||
|
||||
|
||||
class Report ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = conf
|
||||
|
||||
commaspace = ', '
|
||||
date = time.strftime( "%A %d %B %Y" )
|
||||
stateText = 'FAILED'
|
||||
modeText = 'SoC installation'
|
||||
if self.conf.success: stateText = 'SUCCESS'
|
||||
if self.conf.nightlyMode: modeText = 'Nightly build'
|
||||
|
||||
self.message = MIMEMultipart()
|
||||
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
|
||||
self.message['From' ] = self.conf.sender
|
||||
self.message['To' ] = commaspace.join( self.conf.receivers )
|
||||
self.attachements = []
|
||||
|
||||
self.mainText = '\n'
|
||||
self.mainText += 'Salut le Crevard,\n'
|
||||
self.mainText += '\n'
|
||||
if self.conf.nightlyMode:
|
||||
self.mainText += 'This is the nightly build report of Coriolis.\n'
|
||||
else:
|
||||
self.mainText += 'SoC installer report of Coriolis.\n'
|
||||
self.mainText += '%s\n' % date
|
||||
self.mainText += '\n'
|
||||
if self.conf.success:
|
||||
self.mainText += 'Build was SUCCESSFUL\n'
|
||||
else:
|
||||
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
|
||||
self.mainText += '\n'
|
||||
self.mainText += 'Complete log file(s) can be found here:\n'
|
||||
return
|
||||
self.conf = conf
|
||||
|
||||
commaspace = ', '
|
||||
date = time.strftime( "%A %d %B %Y" )
|
||||
stateText = 'FAILED'
|
||||
modeText = 'SoC installation'
|
||||
if self.conf.success: stateText = 'SUCCESS'
|
||||
if self.conf.nightlyMode: modeText = 'Nightly build'
|
||||
|
||||
self.message = MIMEMultipart()
|
||||
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
|
||||
self.message['From' ] = self.conf.sender
|
||||
self.message['To' ] = commaspace.join( self.conf.receivers )
|
||||
self.attachements = []
|
||||
|
||||
self.mainText = '\n'
|
||||
self.mainText += 'Salut le Crevard,\n'
|
||||
self.mainText += '\n'
|
||||
if self.conf.nightlyMode:
|
||||
self.mainText += 'This is the nightly build report of Coriolis.\n'
|
||||
else:
|
||||
self.mainText += 'SoC installer report of Coriolis.\n'
|
||||
self.mainText += '%s\n' % date
|
||||
self.mainText += '\n'
|
||||
if self.conf.success:
|
||||
self.mainText += 'Build was SUCCESSFUL\n'
|
||||
else:
|
||||
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
|
||||
self.mainText += '\n'
|
||||
self.mainText += 'Complete log file(s) can be found here:\n'
|
||||
return
|
||||
|
||||
def attachLog ( self, logFile ):
|
||||
if not logFile: return
|
||||
|
||||
fd = open( logFile, 'rb' )
|
||||
try:
|
||||
fd.seek( -1024*100, os.SEEK_END )
|
||||
except IOError, e:
|
||||
pass
|
||||
tailLines = ''
|
||||
for line in fd.readlines()[1:]:
|
||||
tailLines += line
|
||||
fd.close()
|
||||
self.mainText += ' <%s>\n' % logFile
|
||||
|
||||
attachement = MIMEApplication(tailLines)
|
||||
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
|
||||
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
if not logFile: return
|
||||
|
||||
fd = open( logFile, 'rb' )
|
||||
try:
|
||||
fd.seek( -1024*100, os.SEEK_END )
|
||||
except IOError, e:
|
||||
pass
|
||||
tailLines = ''
|
||||
for line in fd.readlines()[1:]:
|
||||
tailLines += line
|
||||
fd.close()
|
||||
self.mainText += ' <%s>\n' % logFile
|
||||
|
||||
attachement = MIMEApplication(tailLines)
|
||||
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
|
||||
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
|
||||
def send ( self ):
|
||||
self.message.attach( MIMEText(self.mainText) )
|
||||
for attachement in self.attachements:
|
||||
self.message.attach( attachement )
|
||||
|
||||
print "Sending mail report to:"
|
||||
for receiver in self.conf.receivers: print ' <%s>' % receiver
|
||||
session = smtplib.SMTP( 'localhost' )
|
||||
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
|
||||
session.quit()
|
||||
return
|
||||
self.message.attach( MIMEText(self.mainText) )
|
||||
for attachement in self.attachements:
|
||||
self.message.attach( attachement )
|
||||
|
||||
print "Sending mail report to:"
|
||||
for receiver in self.conf.receivers: print ' <%s>' % receiver
|
||||
session = smtplib.SMTP( 'localhost' )
|
||||
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
|
||||
session.quit()
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
|
@ -540,110 +428,105 @@ class Report ( object ):
|
|||
parser = optparse.OptionParser ()
|
||||
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
|
||||
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
|
||||
parser.add_option ( "--do-yosys" , action="store_true" , dest="doYosys" , help="Rebuild Yosys." )
|
||||
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
|
||||
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
|
||||
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
|
||||
parser.add_option ( "--no-build" , action="store_true" , dest="noBuild" , help="Do not rebuild the tools, must have already be done." )
|
||||
parser.add_option ( "--no-report" , action="store_true" , dest="noReport" , help="Do not send a final report." )
|
||||
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
|
||||
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
|
||||
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
|
||||
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
|
||||
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
|
||||
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
|
||||
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
|
||||
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
|
||||
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
|
||||
conf = Configuration()
|
||||
|
||||
try:
|
||||
if options.debug: conf.debugArg = '--debug'
|
||||
if options.nightly: conf.nightlyMode = True
|
||||
if options.docker: conf.dockerMode = True
|
||||
if options.chroot: conf.chrootMode = True
|
||||
if options.noGit: conf.doGit = False
|
||||
if options.doYosys: conf.doYosys = True
|
||||
if options.doAlliance: conf.doAlliance = True
|
||||
if options.doCoriolis: conf.doCoriolis = True
|
||||
if options.noBuild: conf.doBuild = False
|
||||
if options.benchs: conf.doBenchs = True
|
||||
if options.doReport: conf.doSendReport = True
|
||||
if options.noReport: conf.doSendReport = False
|
||||
if options.rmSource or options.rmAll: conf.rmSource = True
|
||||
if options.rmBuild or options.rmAll: conf.rmBuild = True
|
||||
|
||||
|
||||
if conf.doYosys: conf.openLog( 'yosys' )
|
||||
if conf.doAlliance: conf.openLog( 'alliance' )
|
||||
if conf.doCoriolis: conf.openLog( 'coriolis' )
|
||||
if conf.doBenchs: conf.openLog( 'benchs' )
|
||||
|
||||
if conf.dockerMode: os.environ['USER'] = 'root'
|
||||
if conf.doBuild: conf.openLog( 'build' )
|
||||
if conf.doBenchs: conf.openLog( 'benchs' )
|
||||
|
||||
gitSupports = []
|
||||
for supportRepo in conf.supportRepos:
|
||||
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
|
||||
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
|
||||
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
|
||||
|
||||
if conf.doAlliance:
|
||||
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
|
||||
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
|
||||
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['build'] )
|
||||
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['build'] )
|
||||
|
||||
if conf.doGit:
|
||||
for gitSupport in gitSupports:
|
||||
if conf.rmSource: gitSupport.removeLocalRepo()
|
||||
gitSupport.clone()
|
||||
if gitSupport.url.endswith('rapidjson'):
|
||||
gitSupport.checkout( 'b1a4d91' )
|
||||
|
||||
if conf.doAlliance:
|
||||
if conf.rmSource: gitAlliance.removeLocalRepo()
|
||||
gitAlliance.clone ()
|
||||
#gitAlliance.checkout( 'devel' )
|
||||
|
||||
if conf.doCoriolis:
|
||||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
for gitSupport in gitSupports:
|
||||
if conf.rmSource: gitSupport.removeLocalRepo()
|
||||
gitSupport.clone()
|
||||
#if gitSupport.url.endswith('rapidjson'):
|
||||
# gitSupport.checkout( 'a1c4f32' )
|
||||
|
||||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel_anabatic' )
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
|
||||
if conf.rmBuild:
|
||||
for entry in os.listdir(conf.rootDir):
|
||||
if entry.startswith('Linux.'):
|
||||
buildDir = conf.rootDir+'/'+entry
|
||||
print 'Removing OS build directory: <%s>' % buildDir
|
||||
shutil.rmtree( buildDir )
|
||||
for entry in os.listdir(conf.rootDir):
|
||||
if entry.startswith('Linux.'):
|
||||
buildDir = conf.rootDir+'/'+entry
|
||||
print 'Removing OS build directory: <%s>' % buildDir
|
||||
shutil.rmtree( buildDir )
|
||||
|
||||
commands = conf.getCommands( options.profile )
|
||||
for command in commands:
|
||||
if command.host:
|
||||
print 'Executing command on remote host <%s>:' % host
|
||||
else:
|
||||
print 'Executing command on *local* host:'
|
||||
print ' %s' % str(command)
|
||||
command.execute()
|
||||
ccbBin = gitCoriolis.localRepoDir+'/bootstrap/ccb.py'
|
||||
if not os.path.isfile( ccbBin ):
|
||||
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
|
||||
, ' <%s>' % ccbBin
|
||||
] )
|
||||
|
||||
buildCommand = '%s --root=%s --project=support --project=coriolis --make="-j%%d install" %%s' \
|
||||
% (ccbBin,conf.rootDir)
|
||||
benchsCommand = 'cd %s/benchs && ../bin/go.sh' % (gitBenchs.localRepoDir)
|
||||
|
||||
commands = \
|
||||
[ ( conf.targets['SL7_64'], buildCommand % (3,conf.debugArg) , conf.fds['build' ] )
|
||||
, ( conf.targets['SL7_64'], buildCommand % (1,conf.debugArg+' --doc') , conf.fds['build' ] )
|
||||
, ( conf.targets['SL7_64'], benchsCommand , conf.fds['benchs'] )
|
||||
#, ( conf.targets['SL6_64'], buildCommand % (6,conf.debugArg+' --devtoolset-8') , conf.fds['build' ] )
|
||||
#, ( conf.targets['SL6_64'], buildCommand % (1,conf.debugArg+' --devtoolset-8 --doc'), conf.fds['build' ] )
|
||||
#, ( conf.targets['SL6_64'], benchsCommand , conf.fds['benchs'] )
|
||||
#, ( conf.targets['SL6'] , buildCommand % (2,conf.debugArg+' --devtoolset-8') , conf.fds['build' ] )
|
||||
#, ( conf.targets['SL6'] , buildCommand % (1,conf.debugArg+' --devtoolset-8 --doc'), conf.fds['build' ] )
|
||||
#, ( conf.targets['SL6'] , benchsCommand , conf.fds['benchs'] )
|
||||
]
|
||||
|
||||
for host,command,fd in commands:
|
||||
if host and fd:
|
||||
print 'Executing command on <%s>:' % host
|
||||
print ' %s' % command
|
||||
Command( [ 'ssh', host, command ], fd ).execute()
|
||||
|
||||
conf.closeLogs()
|
||||
|
||||
conf.success = True
|
||||
|
||||
except ErrorMessage, e:
|
||||
print e
|
||||
conf.closeLogs()
|
||||
conf.success = False
|
||||
|
||||
if showTrace:
|
||||
print '\nPython stack trace:'
|
||||
traceback.print_tb( sys.exc_info()[2] )
|
||||
conf.rcode = e.code
|
||||
print e
|
||||
conf.closeLogs()
|
||||
conf.success = False
|
||||
|
||||
if showTrace:
|
||||
print '\nPython stack trace:'
|
||||
traceback.print_tb( sys.exc_info()[2] )
|
||||
conf.rcode = e.code
|
||||
|
||||
if conf.doSendReport:
|
||||
report = Report( conf )
|
||||
report.attachLog( conf.logs['coriolis' ] )
|
||||
report.attachLog( conf.logs['benchs' ] )
|
||||
report.send()
|
||||
report = Report( conf )
|
||||
report.attachLog( conf.logs['build' ] )
|
||||
report.attachLog( conf.logs['benchs'] )
|
||||
report.send()
|
||||
|
||||
conf.compressLogs()
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
srcDir=${HOME}
|
||||
gitHash="6edca05"
|
||||
|
||||
cd ${srcDir}
|
||||
git clone https://github.com/cliffordwolf/yosys.git
|
||||
cd yosys
|
||||
git checkout ${gitHash}
|
||||
make config-gcc
|
||||
make GIT_REV=${gitHash} -j4
|
||||
make GIT_REV=${gitHash} install
|
|
@ -267,7 +267,7 @@ namespace Bora {
|
|||
slicingtree->expandRoutingChannel();
|
||||
slicingtree->replace();
|
||||
slicingtree->updateSymNetAxis();
|
||||
|
||||
|
||||
katana->updateMatrix();
|
||||
katana->analogInit();
|
||||
Katana::Session::close();
|
||||
|
|
|
@ -189,10 +189,7 @@ namespace Bora {
|
|||
{
|
||||
cdebug_log(535,1) << "HSlicingNode::updateGlobalsize() - " << this << endl;
|
||||
|
||||
for ( SlicingNode* child : _children ) {
|
||||
cdebug_log(535,0) << "child: " << child << endl;
|
||||
child->updateGlobalSize();
|
||||
}
|
||||
for ( SlicingNode* child : _children ) child->updateGlobalSize();
|
||||
|
||||
if (not getMaster()) {
|
||||
if (getNbChild() == 1) {
|
||||
|
|
|
@ -377,14 +377,10 @@ namespace Bora {
|
|||
if (getType() == HorizontalSNode) symmetryType = HSymmetry;
|
||||
if (getType() == VerticalSNode ) symmetryType = VSymmetry;
|
||||
|
||||
|
||||
if (not getChild(childIndex)->isSymmetric(getChild(copyIndex), symmetryType, ShowDiff)) {
|
||||
cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored.\n"
|
||||
" child %d: %s\n"
|
||||
" child %d: %s"
|
||||
, childIndex, copyIndex
|
||||
, childIndex, getString(getChild(childIndex)).c_str()
|
||||
, copyIndex , getString(getChild( copyIndex)).c_str()
|
||||
) << endl;
|
||||
cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored."
|
||||
, childIndex, copyIndex ) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1132,9 +1128,6 @@ namespace Bora {
|
|||
|
||||
void HVSlicingNode::addSymmetryNet ( unsigned int type, Net* net1, Net* net2 )
|
||||
{
|
||||
cerr << "HVSlicingNode::addSymmetryNet(): " << this << endl;
|
||||
cerr << "* " << net1 << endl;
|
||||
|
||||
if (checkSymmetryNet(type,net1,net2)) {
|
||||
cerr << Warning( "HVSlicingNode::addSymmetryNet(): Net symmetry already set." ) << endl;
|
||||
return;
|
||||
|
@ -1208,13 +1201,6 @@ namespace Bora {
|
|||
}
|
||||
|
||||
for ( const NetSymmetry& symNet : _netSymmetries ) {
|
||||
if (_symmetries.empty())
|
||||
throw Error( "HVSlicingNode::updateSymNetAxis(): \n"
|
||||
" Symmetry request for \"%s\" in non-symmetrical node \"%s\"."
|
||||
, getString(get<1>(symNet)->getName()).c_str()
|
||||
, getString(this).c_str()
|
||||
);
|
||||
|
||||
SlicingNode* n1 = getChild( _symmetries.front().first );
|
||||
SlicingNode* n2 = getChild( _symmetries.front().second );
|
||||
DbU::Unit xCenter = (n1->getX() + n2->getX() + n2->getWidth())/2;
|
||||
|
@ -1262,11 +1248,11 @@ namespace Bora {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( SlicingNode* child : _children ) {
|
||||
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
|
||||
child->updateSymNetAxis();
|
||||
for ( SlicingNode* child : _children ) {
|
||||
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
|
||||
child->updateSymNetAxis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,8 +70,7 @@ namespace Bora {
|
|||
TransistorFamily* device = dynamic_cast<TransistorFamily *>( cell );
|
||||
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
|
||||
if (device) {
|
||||
cdebug_log(535,0) << "NodeSets:create(): for a Transistor Analog Device" << endl;
|
||||
|
||||
//cdebug_log(536,0) << "createNodeSets for an Analog Device" << endl;
|
||||
if (not stepRange) {
|
||||
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
|
||||
, getString(device->getName()).c_str()
|
||||
|
@ -95,34 +94,30 @@ namespace Bora {
|
|||
MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( nodeset->getRange() );
|
||||
|
||||
if (mcapacitor) {
|
||||
cdebug_log(535,0) << "NodeSets::create(): for a Capacitor Analog Device" << endl;
|
||||
|
||||
if (not matrixRange) {
|
||||
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s."
|
||||
, getString(mcapacitor->getName()).c_str()
|
||||
, getString(stepRange).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
matrixRange->reset();
|
||||
do {
|
||||
MatrixParameter* mp = NULL;
|
||||
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
|
||||
mp->setMatrix( &matrixRange->getValue() );
|
||||
matrixRange->reset();
|
||||
do {
|
||||
MatrixParameter* mp = NULL;
|
||||
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
|
||||
mp->setMatrix( &matrixRange->getValue() );
|
||||
|
||||
layoutGenerator->setDevice( mcapacitor );
|
||||
layoutGenerator->drawLayout();
|
||||
layoutGenerator->setDevice( mcapacitor );
|
||||
layoutGenerator->drawLayout();
|
||||
|
||||
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
|
||||
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
|
||||
|
||||
matrixRange->progress();
|
||||
} while ( matrixRange->isValid() );
|
||||
matrixRange->progress();
|
||||
} while ( matrixRange->isValid() );
|
||||
}
|
||||
} else {
|
||||
ResistorFamily* device = dynamic_cast<ResistorFamily *>( cell );
|
||||
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
|
||||
if (device) {
|
||||
cdebug_log(535,0) << "NodeSets::create(): for a Resistor Analog Device" << endl;
|
||||
|
||||
if (not stepRange) {
|
||||
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
|
||||
, getString(device->getName()).c_str()
|
||||
|
@ -339,6 +334,7 @@ namespace Bora {
|
|||
if (find(boxSet) == NULL) _boxSets.push_back( boxSet );
|
||||
else {
|
||||
find( boxSet )->incrementCpt();
|
||||
cerr << "NodeSets::push_back(): do not add current BoxSet, already exists." << endl;
|
||||
boxSet->destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "crlcore/PyRoutingGauge.h"
|
||||
#include "bora/PyDSlicingNode.h"
|
||||
#include "bora/PyStepParameterRange.h"
|
||||
#include "bora/PyMatrixParameterRange.h"
|
||||
|
||||
|
||||
namespace Bora {
|
||||
|
@ -74,10 +73,8 @@ extern "C" {
|
|||
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Second argument *must* be of type Cell." );
|
||||
return NULL;
|
||||
}
|
||||
if ( (pyParameterRange != Py_None)
|
||||
and not IsPyStepParameterRange(pyParameterRange)
|
||||
and not IsPyMatrixParameterRange(pyParameterRange)) {
|
||||
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange or MatrixParameterRange." );
|
||||
if (not IsPyStepParameterRange(pyParameterRange)) {
|
||||
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange." );
|
||||
return NULL;
|
||||
}
|
||||
if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) {
|
||||
|
@ -85,18 +82,10 @@ extern "C" {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Cell* cell = PYCELL_O( pyCell );
|
||||
Instance* instance = cell->getInstance( PyString_AsString(pyInstance) );
|
||||
if (not instance) {
|
||||
ostringstream message;
|
||||
message << "DSlicingNode.create(): Cell \"" << cell->getName()
|
||||
<< "\" has no instance named \"" << PyString_AsString(pyInstance) << "\".";
|
||||
PyErr_SetString( ConstructorError, message.str().c_str() );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ParameterRange* range = ParameterRangeCast( pyParameterRange );
|
||||
RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL;
|
||||
Cell* cell = PYCELL_O( pyCell );
|
||||
Instance* instance = cell->getInstance( PyString_AsString(pyInstance) );
|
||||
ParameterRange* range = ParameterRangeCast( pyParameterRange );
|
||||
RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL;
|
||||
|
||||
node = DSlicingNode::create( NodeSets::create( instance->getMasterCell(), range, rg )
|
||||
, UnknownAlignment
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "bora/PyParameterRange.h"
|
||||
#include "bora/PyStepParameterRange.h"
|
||||
#include "bora/PyMatrixParameterRange.h"
|
||||
|
||||
|
||||
namespace Bora {
|
||||
|
@ -113,9 +112,7 @@ extern "C" {
|
|||
# if !defined(__PYTHON_MODULE__)
|
||||
|
||||
ParameterRange* ParameterRangeCast ( PyObject* derivedObject ) {
|
||||
if (not derivedObject or (derivedObject == Py_None)) return NULL;
|
||||
if (IsPyStepParameterRange (derivedObject)) return PYSTEPPARAMETERRANGE_O (derivedObject);
|
||||
if (IsPyMatrixParameterRange(derivedObject)) return PYMATRIXPARAMETERRANGE_O(derivedObject);
|
||||
if (IsPyStepParameterRange(derivedObject)) return PYSTEPPARAMETERRANGE_O(derivedObject);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -77,11 +77,12 @@ namespace Bora {
|
|||
NodeSets nodeSets = slicingtree->getNodeSets();
|
||||
switch ( index.column() ) {
|
||||
case 0: return QVariant( row );
|
||||
case 1: return QVariant( DbU::toPhysical(nodeSets[row]->getHeight(), DbU::Micro) );
|
||||
case 2: return QVariant( DbU::toPhysical(nodeSets[row]->getWidth (), DbU::Micro) );
|
||||
case 3: return QVariant( nodeSets[row]->getOccupationArea() );
|
||||
case 4: return QVariant( nodeSets[row]->getCpt() );
|
||||
case 5: return QVariant( nodeSets[row]->getRatio() );
|
||||
case 1: return QVariant( DbU::toPhysical(nodeSets[row]->getHeight() , DbU::Micro) );
|
||||
case 2: return QVariant( DbU::toPhysical(nodeSets[row]->getWidth() , DbU::Micro) );
|
||||
case 3: return QVariant( nodeSets[row]->getOccupationArea() );
|
||||
case 4: return QVariant( nodeSets[row]->getCpt() );
|
||||
case 5: return QVariant( (double) ( nodeSets[row]->getWidth()
|
||||
/ nodeSets[row]->getHeight()) );
|
||||
case 6: return QVariant( DbU::getPhysical( nodeSets[row]->getWidth() ,DbU::Micro)
|
||||
* DbU::getPhysical( nodeSets[row]->getHeight(),DbU::Micro) );
|
||||
default:
|
||||
|
|
|
@ -698,9 +698,6 @@ namespace Bora {
|
|||
for ( RoutingPad* rp : net->getRoutingPads() ) rps.push_back( rp );
|
||||
for ( RoutingPad* rp : rps ) rp->destroy();
|
||||
}
|
||||
|
||||
_cell->getFlags().reset( Cell::Flags::FlattenedNets|Cell::Flags::Routed );
|
||||
_cell->setTerminalNetlist( false );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -399,11 +399,9 @@ namespace Bora {
|
|||
|
||||
if (device) {
|
||||
TransistorFamily* tf = dynamic_cast<TransistorFamily*>( device );
|
||||
if (tf) {
|
||||
_gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) );
|
||||
i++;
|
||||
}
|
||||
if (tf) _gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ namespace Bora {
|
|||
DbU::Unit addedDistance = 0;
|
||||
|
||||
if (Vertex::isRestricted(vcurr, vnext, e, _hpitch, _vpitch, _net)) {
|
||||
cdebug_log(112,1) << "Unreachable, restricted "<< e << std::endl;
|
||||
distance = Vertex::unreachable;
|
||||
} else {
|
||||
if ( (vcurr->getGCell()->isMatrix()) and (vnext->getGCell()->isMatrix()) ) {
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace Bora {
|
|||
inline DbU::Unit BoxSet::getWidth () const { return _width; }
|
||||
inline unsigned int BoxSet::getCpt () const { return _cpt; }
|
||||
inline void BoxSet::incrementCpt () { _cpt++; }
|
||||
inline double BoxSet::getRatio () { return (double)_width/(double)_height; }
|
||||
inline double BoxSet::getRatio () { return _width/_height; }
|
||||
inline double BoxSet::getArea () { return _width*_height; }
|
||||
inline unsigned int BoxSet::getType () const { return UnknownType; }
|
||||
inline double BoxSet::getOccupationArea () const { return 100; }
|
||||
|
|
|
@ -26,7 +26,7 @@ IF(UNIX)
|
|||
FIND_LIBRARY(COLOQUINTE_LIBRARY_PATH
|
||||
NAMES coloquinte
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATH_SUFFIXES lib${LIB_SUFFIX}
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
|
|
@ -159,13 +159,6 @@ class netlist{
|
|||
index_t get_cell_ind(index_t external_ind) const{ return cell_internal_mapping_[external_ind]; }
|
||||
index_t get_net_ind(index_t external_ind) const{ return net_internal_mapping_[external_ind]; }
|
||||
|
||||
point<int_t> get_cell_size(index_t external_ind){
|
||||
return cell_sizes_[ cell_internal_mapping_[external_ind] ];
|
||||
}
|
||||
|
||||
void set_cell_size(index_t external_ind,point<int_t> cell_size){
|
||||
cell_sizes_[cell_internal_mapping_[external_ind]] = cell_size;
|
||||
}
|
||||
};
|
||||
|
||||
inline netlist::netlist(std::vector<temporary_cell> cells, std::vector<temporary_net> nets, std::vector<temporary_pin> all_pins){
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "coloquinte/optimization_subproblems.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <queue>
|
||||
|
@ -398,6 +397,7 @@ detailed_placement legalize(netlist const & circuit, placement_t const & pl, box
|
|||
int_t rnd_hgh_y_pos = std::min(surface.y_max, hgh_y_pos);
|
||||
int_t rnd_low_x_pos = std::max(surface.x_min, low_x_pos);
|
||||
int_t rnd_low_y_pos = std::max(surface.y_min, low_y_pos);
|
||||
|
||||
index_t first_row = (rnd_low_y_pos - surface.y_min) / row_height;
|
||||
index_t last_row = (index_t) (rnd_hgh_y_pos - surface.y_min + row_height - 1) / row_height; // Exclusive: if the cell spans the next row, i.e. pos % row_height >= 0, include it too
|
||||
assert(last_row <= nbr_rows);
|
||||
|
@ -415,12 +415,8 @@ detailed_placement legalize(netlist const & circuit, placement_t const & pl, box
|
|||
std::sort(L.begin(), L.end()); // Sorts from last to first, so that we may use pop_back()
|
||||
// Doesn't collapse them yet, which may make for bigger complexities
|
||||
for(index_t i=0; i+1<L.size(); ++i){
|
||||
if(L[i].min_x < L[i+1].max_x) {
|
||||
std::ostringstream message;
|
||||
message << "Coloquinte::dp::legalize(): Sorry, I don't handle overlapping fixed cells yet ";
|
||||
message << " i:" << i << " max_x: " << L[i].max_x << " > min_x:" << L[i+1].min_x << "\n";
|
||||
throw std::runtime_error(message.str());
|
||||
}
|
||||
if(L[i].min_x < L[i+1].max_x)
|
||||
throw std::runtime_error("Sorry, I don't handle overlapping fixed cells yet\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ box<int_t> region_distribution::get_box(index_t x, index_t y, index_t x_cnt, ind
|
|||
placement_area_.y_min + ( ((std::int64_t) (placement_area_.y_max - placement_area_.y_min)) * y ) / y_cnt,
|
||||
placement_area_.y_min + ( ((std::int64_t) (placement_area_.y_max - placement_area_.y_min)) * (y+1) ) / y_cnt
|
||||
);
|
||||
//assert(not ret.empty());
|
||||
assert(not ret.empty());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1008,7 +1008,7 @@ std::vector<region_distribution::movable_cell> region_distribution::export_sprea
|
|||
index_t n = R.cell_references_.size();
|
||||
float_t total_capacity = static_cast<float_t>(R.capacity());
|
||||
box<float_t> surface = static_cast<box<float_t> >(get_box(x, y, x_regions_cnt(), y_regions_cnt()));
|
||||
//assert(surface.x_max > surface.x_min and surface.y_max > surface.y_min);
|
||||
assert(surface.x_max > surface.x_min and surface.y_max > surface.y_min);
|
||||
|
||||
std::vector<legalizable_task<float_t> > x_cells, y_cells;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ IF(UNIX)
|
|||
FIND_LIBRARY(CRLCORE_LIBRARY_PATH
|
||||
NAMES crlcore
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATH_SUFFIXES lib${LIB_SUFFIX}
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${CORIOLIS_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ IF(UNIX)
|
|||
FIND_LIBRARY(LIBMANAGER_LIBRARY_PATH
|
||||
NAMES libmanager
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATH_SUFFIXES lib${LIB_SUFFIX}
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${CORIOLIS_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
@ -50,7 +50,7 @@ IF(UNIX)
|
|||
FIND_LIBRARY(CORIOLIS_PYTHON_LIBRARY_PATH
|
||||
NAMES pycrlcore
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATH_SUFFIXES lib${LIB_SUFFIX}
|
||||
# Help the user find it if we cannot.
|
||||
DOC "${CORIOLIS_LIBRARY_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- mode: CMAKE; explicit-buffer-name: # "CMakeLists.txt<crlcore/doc/crlcore>" -*-
|
||||
|
||||
set ( htmlInstallDir share/doc/coriolis2/en/html/doc/crlcore )
|
||||
set ( htmlInstallDir share/doc/coriolis2/en/html/crlcore )
|
||||
set ( latexInstallDir share/doc/coriolis2/en/latex/crlcore )
|
||||
set ( doxExtras closed.png
|
||||
open.png
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 {
|
||||
font-size: 11pt;
|
||||
/* The Open Sans font family is supplied by TexLive. */
|
||||
font-family: "Roboto", "Open Sans", Verdana, sans-serif;;
|
||||
font-family: "Open Sans", Verdana, sans-serif;;
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -598,7 +598,7 @@
|
|||
*/
|
||||
|
||||
div.fragment {
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
font-family: "Monospace";
|
||||
font-size: 80%;
|
||||
border: none;
|
||||
/*border-width: thin; */
|
||||
|
@ -610,16 +610,6 @@
|
|||
margin-right: 5%
|
||||
}
|
||||
|
||||
div.fragment a.code:link,
|
||||
div.fragment a.code:visited,
|
||||
div.fragment a.codeRef:link,
|
||||
div.fragment a.codeRef:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.line {
|
||||
white-space: pre;
|
||||
padding: 0pt;
|
||||
|
@ -641,7 +631,7 @@
|
|||
*/
|
||||
|
||||
a.el, a.elRef {
|
||||
font-family: "Roboto Mono", Courier;
|
||||
font-family: Courier;
|
||||
font-weight: bold;
|
||||
font-size: 110%;
|
||||
color: black;
|
||||
|
@ -708,7 +698,7 @@
|
|||
}
|
||||
|
||||
table.memname * {
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
font-family: "Monospace";
|
||||
}
|
||||
|
||||
|
||||
|
@ -754,7 +744,7 @@
|
|||
/*background-color: #eeeeff;*/
|
||||
/*background-color: #EEEEEE;*/
|
||||
/*background-color: #CCE6CA;*/
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
font-family: "Monospace";
|
||||
}
|
||||
|
||||
.memTemplItemLeft, .memTemplItemRight {
|
||||
|
@ -763,7 +753,7 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.memItemLeft { font-size: 11px; width: 100pt; }
|
||||
.memItemLeft { font-size: 11px; width: 35%; }
|
||||
.memItemRight { font-size: 12px; }
|
||||
.memTemplItemLeft { font-size: 11px; }
|
||||
.memTemplItemRight { font-size: 12px; }
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Coriolis Core (CRL)</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite, All rights reserved</small></td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2016 UPMC All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
|
@ -48,20 +48,20 @@ $(function() {
|
|||
<div class="ttc" id="classCRL_1_1AcmSigda_html_a5e61fb60049f5a2dca1f2ca05fd5857a"><div class="ttname"><a href="classCRL_1_1AcmSigda.html#a5e61fb60049f5a2dca1f2ca05fd5857a">CRL::AcmSigda::load</a></div><div class="ttdeci">static Cell * load(std::string benchmark)</div></div>
|
||||
<div class="ttc" id="classCRL_1_1AcmSigda_html"><div class="ttname"><a href="classCRL_1_1AcmSigda.html">CRL::AcmSigda</a></div><div class="ttdoc">A Parser of ACM/Sigda 89&#39; benchmarks. </div><div class="ttdef"><b>Definition:</b> AcmSigda.h:33</div></div>
|
||||
<div class="ttc" id="namespaceHurricane_html"><div class="ttname"><a href="namespaceHurricane.html">Hurricane</a></div></div>
|
||||
<div class="ttc" id="namespaceCRL_html"><div class="ttname"><a href="namespaceCRL.html">CRL</a></div><div class="ttdoc">The namespace of Coriolis Core. </div><div class="ttdef"><b>Definition:</b> Environment.h:24</div></div>
|
||||
<div class="ttc" id="namespaceCRL_html"><div class="ttname"><a href="namespaceCRL.html">CRL</a></div><div class="ttdoc">The namespace of Coriolis Core. </div><div class="ttdef"><b>Definition:</b> Environment.h:26</div></div>
|
||||
</div><!-- fragment --></div><!-- contents -->
|
||||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Thu Nov 12 2020</small></td>
|
||||
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Coriolis Core (CRL)</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite, All rights reserved</small></td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2016 UPMC All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -59,21 +59,21 @@ $(function() {
|
|||
<div class="ttc" id="classCRL_1_1Banner_html_aa61a32222853ae9f4298302ca53788bc"><div class="ttname"><a href="classCRL_1_1Banner.html#aa61a32222853ae9f4298302ca53788bc">CRL::Banner::getAuthors</a></div><div class="ttdeci">const string & getAuthors() const</div><div class="ttdef"><b>Definition:</b> Banner.h:177</div></div>
|
||||
<div class="ttc" id="classCRL_1_1Banner_html"><div class="ttname"><a href="classCRL_1_1Banner.html">CRL::Banner</a></div><div class="ttdoc">Print Formatted Banners (on ttys). </div><div class="ttdef"><b>Definition:</b> Banner.h:114</div></div>
|
||||
<div class="ttc" id="classCRL_1_1Banner_html_a240b3f305516b17eff31f684d0a5c643"><div class="ttname"><a href="classCRL_1_1Banner.html#a240b3f305516b17eff31f684d0a5c643">CRL::Banner::getName</a></div><div class="ttdeci">const string & getName() const</div><div class="ttdef"><b>Definition:</b> Banner.h:173</div></div>
|
||||
<div class="ttc" id="namespaceCRL_html"><div class="ttname"><a href="namespaceCRL.html">CRL</a></div><div class="ttdoc">The namespace of Coriolis Core. </div><div class="ttdef"><b>Definition:</b> Environment.h:24</div></div>
|
||||
<div class="ttc" id="namespaceCRL_html"><div class="ttname"><a href="namespaceCRL.html">CRL</a></div><div class="ttdoc">The namespace of Coriolis Core. </div><div class="ttdef"><b>Definition:</b> Environment.h:26</div></div>
|
||||
<div class="ttc" id="classCRL_1_1Banner_html_a9c6bee971231044f417aaac312abcb61"><div class="ttname"><a href="classCRL_1_1Banner.html#a9c6bee971231044f417aaac312abcb61">CRL::Banner::setPurpose</a></div><div class="ttdeci">void setPurpose(string purpose)</div></div>
|
||||
</div><!-- fragment --></div><!-- contents -->
|
||||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Thu Nov 12 2020</small></td>
|
||||
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Coriolis Core (CRL)</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite, All rights reserved</small></td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2016 UPMC All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue