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,22 +437,7 @@ 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -533,10 +445,6 @@ namespace Anabatic {
|
|||
{ 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;
|
||||
|
@ -1793,17 +1574,16 @@ namespace Anabatic {
|
|||
} 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,32 +1598,13 @@ namespace Anabatic {
|
|||
perpandicular->incReduceds();
|
||||
}
|
||||
|
||||
// if (not source->isTerminal()) source->getPerpandicular( this )->incReduceds();
|
||||
// if (not target->isTerminal()) target->getPerpandicular( this )->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;
|
||||
}
|
||||
|
||||
return nonReduceds;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::mustRaise () const
|
||||
{
|
||||
if (not (_flags & SegIsReduced)) return false;
|
||||
|
@ -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_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_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_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"
|
||||
|
@ -1139,41 +1069,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
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 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 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 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 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 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* );
|
||||
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;
|
||||
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
|
||||
|
||||
return (osType,useDevtoolset)
|
||||
if libDir == 'lib64' and not os.path.exists('/usr/lib64'):
|
||||
libDir = 'lib'
|
||||
|
||||
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) ]
|
||||
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')
|
||||
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
|
||||
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
|
||||
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()
|
||||
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)
|
||||
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)
|
||||
|
||||
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 )
|
||||
try:
|
||||
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
|
||||
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
while True:
|
||||
line = child.stdout.readline()
|
||||
if not line: break
|
||||
|
||||
self.log( line )
|
||||
except OSError, e:
|
||||
raise BadBinary( self.arguments[0] )
|
||||
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
|
||||
(pid,status) = os.waitpid( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
raise BadReturnCode( status )
|
||||
|
||||
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 )
|
||||
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
|
||||
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._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
|
||||
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)
|
||||
|
||||
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
|
||||
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 )
|
||||
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
|
||||
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
|
||||
for log in self._logs.values():
|
||||
if not log: continue
|
||||
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
fd = open( log, 'r' )
|
||||
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
|
||||
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
for line in fd.readlines(): bzfd.write( line )
|
||||
|
||||
bzfd.close()
|
||||
fd.close()
|
||||
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
|
||||
os.unlink( log )
|
||||
return
|
||||
|
||||
|
||||
class Report ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = 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'
|
||||
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.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.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
|
||||
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
|
||||
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) )
|
||||
attachement = MIMEApplication(tailLines)
|
||||
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
|
||||
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
self.attachements.append( attachement )
|
||||
return
|
||||
|
||||
def send ( self ):
|
||||
self.message.attach( MIMEText(self.mainText) )
|
||||
for attachement in self.attachements:
|
||||
self.message.attach( attachement )
|
||||
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
|
||||
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' )
|
||||
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.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel_anabatic' )
|
||||
|
||||
if conf.doCoriolis:
|
||||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
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
|
||||
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 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
|
|
@ -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() );
|
||||
|
||||
layoutGenerator->setDevice( mcapacitor );
|
||||
layoutGenerator->drawLayout();
|
||||
|
||||
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
|
||||
|
||||
matrixRange->progress();
|
||||
} while ( matrixRange->isValid() );
|
||||
}
|
||||
|
||||
matrixRange->reset();
|
||||
do {
|
||||
MatrixParameter* mp = NULL;
|
||||
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
|
||||
mp->setMatrix( &matrixRange->getValue() );
|
||||
|
||||
layoutGenerator->setDevice( mcapacitor );
|
||||
layoutGenerator->drawLayout();
|
||||
|
||||
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
|
||||
|
||||
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
|
@ -54,20 +54,20 @@ $(function() {
|
|||
<div class="ttc" id="classHurricane_1_1CellViewer_html"><div class="ttname"><a href="../viewer/classHurricane_1_1CellViewer.html">Hurricane::CellViewer</a></div></div>
|
||||
<div class="ttc" id="namespaceHurricane_html"><div class="ttname"><a href="namespaceHurricane.html">Hurricane</a></div></div>
|
||||
<div class="ttc" id="classHurricane_1_1CellWidget_html"><div class="ttname"><a href="../viewer/classHurricane_1_1CellWidget.html">Hurricane::CellWidget</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>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue