From 9501b88110b8a76a89f11603028f62759c6b6345 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 25 Mar 2014 00:59:12 +0100 Subject: [PATCH] First barebone implementation of Etesian. Support for ISPD05 benchmark. Details: * New: In , new objet Dots for displaying a kind of progress bar. * Change: In , keywords are now case-insensitive. Added a "strict syntax" option (to be disabled for ISPD05). * New: First working implementation of Etesian, at least for ISPD05 "bigblue1". * Change: In , in Cell::flattenNets(), no longer display a warning if an instance is unplaced, this does not make sense when the circuit is not placed. * New: In , Added translator for ISPD05 bookshelf, the circuit is *not* placed, unlike in ISPD04 and terminal nodes *are* true cells. * New: In , added entry in import cell for ISPD05 benchmarks. --- crlcore/src/ccore/crlcore/Ispd05Bookshelf.h | 4 +- crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp | 198 ++++++++---------- etesian/src/EtesianEngine.cpp | 176 +++++++++++++--- etesian/src/GraphicEtesianEngine.cpp | 5 + etesian/src/etesian/EtesianEngine.h | 11 +- hurricane/src/hurricane/Cell.cpp | 2 +- unicorn/src/CMakeLists.txt | 2 + unicorn/src/CgtMain.cpp | 6 +- unicorn/src/UnicornGui.cpp | 2 - vlsisapd/src/bookshelf/src/Bookshelf.cpp | 2 +- vlsisapd/src/bookshelf/src/Circuit.cpp | 14 +- vlsisapd/src/bookshelf/src/Parser.cpp | 144 +++++++------ vlsisapd/src/bookshelf/src/Pin.cpp | 15 +- .../src/vlsisapd/bookshelf/Circuit.h | 29 +-- .../bookshelf/src/vlsisapd/bookshelf/Node.h | 19 +- .../bookshelf/src/vlsisapd/bookshelf/Parser.h | 21 +- .../bookshelf/src/vlsisapd/bookshelf/Pin.h | 26 +-- .../bookshelf/src/vlsisapd/bookshelf/Row.h | 21 +- vlsisapd/src/utilities/src/CMakeLists.txt | 12 +- vlsisapd/src/utilities/src/Dots.cpp | 53 +++++ vlsisapd/src/utilities/src/Path.cpp | 3 +- .../utilities/src/vlsisapd/utilities/Dots.h | 85 ++++++++ 22 files changed, 541 insertions(+), 309 deletions(-) create mode 100644 vlsisapd/src/utilities/src/Dots.cpp create mode 100644 vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h diff --git a/crlcore/src/ccore/crlcore/Ispd05Bookshelf.h b/crlcore/src/ccore/crlcore/Ispd05Bookshelf.h index 262588f8..c1280e72 100644 --- a/crlcore/src/ccore/crlcore/Ispd05Bookshelf.h +++ b/crlcore/src/ccore/crlcore/Ispd05Bookshelf.h @@ -14,8 +14,8 @@ // +-----------------------------------------------------------------+ -#ifndef CRL_ISPD05_BOOKSHELF -#define CRL_ISPD05_BOOKSHELF +#ifndef CRL_ISPD05_BOOKSHELF_H +#define CRL_ISPD05_BOOKSHELF_H #include diff --git a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp index 525b29d4..ae14f535 100644 --- a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp +++ b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp @@ -15,11 +15,14 @@ #include +#include "vlsisapd/utilities/Dots.h" #include "vlsisapd/bookshelf/Exception.h" #include "vlsisapd/bookshelf/Node.h" #include "vlsisapd/bookshelf/Pin.h" #include "vlsisapd/bookshelf/Net.h" +#include "vlsisapd/bookshelf/Row.h" #include "vlsisapd/bookshelf/Circuit.h" +#include "vlsisapd/bookshelf/Parser.h" #include "hurricane/Error.h" #include "hurricane/Warning.h" #include "hurricane/DataBase.h" @@ -31,6 +34,7 @@ #include "hurricane/Cell.h" #include "hurricane/Library.h" #include "hurricane/UpdateSession.h" +#include "crlcore/Utilities.h" #include "crlcore/AllianceFramework.h" #include "crlcore/ToolBox.h" #include "crlcore/Ispd05Bookshelf.h" @@ -43,6 +47,9 @@ namespace { using namespace CRL; + DbU::Unit pitch = 5.0; + + void addSupplyNets ( Cell* cell ) { Net* vss = Net::create ( cell, "vss" ); @@ -59,70 +66,45 @@ namespace { Cell* toMasterCell ( AllianceFramework* af, Bookshelf::Node* node ) { - if ( node->getHeight() > 16.0 ) return NULL; - Technology* technology = DataBase::getDB()->getTechnology(); Layer* METAL1 = technology->getLayer ( "METAL1" ); - Cell* master = af->createCell ( node->getName() ); - Box abutmentBox ( DbU::lambda( 0.0 ) - , DbU::lambda( 0.0 ) - , DbU::lambda( node->getWidth()*5.0 ) - , DbU::lambda( 50.0 ) - ); - master->setAbutmentBox ( abutmentBox ); + Cell* master = af->createCell( node->getName() ); + Box abutmentBox( DbU::fromLambda( 0.0 ) + , DbU::fromLambda( 0.0 ) + , DbU::fromLambda( node->getWidth ()*pitch ) + , DbU::fromLambda( node->getHeight()*pitch ) + ); + master->setAbutmentBox( abutmentBox ); + Point cellCenter = abutmentBox.getCenter(); - addSupplyNets ( master ); + addSupplyNets( master ); - Segment* segment = Horizontal::create ( master->getNet("vss") + for ( auto ipin : node->getPins() ) { + Bookshelf::Pin* pin = ipin.second; + Point pinCenter ( cellCenter.getX() + DbU::fromLambda(pin->getX()*pitch) + , cellCenter.getY() + DbU::fromLambda(pin->getY()*pitch) ); + if (not abutmentBox.contains(pinCenter)) + cerr << Error( "Ispd05::load(): Pin <%s> of node <%s> is outside abutment box.\n" + " (AB:[%dx%d], pin:(%d,%d))" + , pin->getNet()->getName().c_str() + , getString(node->getName()).c_str() + , node->getWidth(), node->getHeight() + , pin->getX() , pin->getY() ) << endl;; + + Net* net = master->getNet( pin->getNet()->getName() ); + if (not net) + net = Net::create( master, pin->getNet()->getName() ); + net->setExternal( true ); + + Vertical* segment = Vertical::create( net , METAL1 - , abutmentBox.getYMin()+DbU::lambda(3.0) - , DbU::lambda(6.0) - , abutmentBox.getXMin() - , abutmentBox.getXMax() + , pinCenter.getX() + , DbU::fromLambda(2.0) + , pinCenter.getY() - DbU::fromLambda(0.5) + , pinCenter.getY() + DbU::fromLambda(0.5) ); - NetExternalComponents::setExternal ( segment ); - - segment = Horizontal::create ( master->getNet("vdd") - , METAL1 - , abutmentBox.getYMax()-DbU::lambda(3.0) - , DbU::lambda( 6.0) - , abutmentBox.getXMin() - , abutmentBox.getXMax() - ); - NetExternalComponents::setExternal ( segment ); - - map& pins = node->getPins(); - map::iterator ipin = pins.begin(); - - if ( node->getWidth() < (double)pins.size() ) - throw Error("Ispd05::load(): Node <%s> has only %.1f pitchs, cannot hold %zd terminals." - ,node->getName().c_str(),node->getWidth(),pins.size()); - - DbU::Unit pinXMin = abutmentBox.getXMin() + DbU::lambda(5.0); - DbU::Unit pinXMax = abutmentBox.getXMax() - ((node->getWidth() > (double)pins.size()) ? DbU::lambda(5.0) : 0); - DbU::Unit pinX; - - for ( size_t pinnb=0 ; ipin != pins.end() ; ++ipin, ++pinnb ) { - Net* net = Net::create ( master, (*ipin).second->getNet()->getName() ); - net->setExternal ( true ); - - if ( pinnb % 2 ) { - pinX = pinXMax; - pinXMax -= DbU::lambda(5.0); - } else { - pinX = pinXMin; - pinXMin += DbU::lambda(5.0); - } - - segment = Vertical::create ( net - , METAL1 - , pinX - , DbU::lambda(1.0) - , abutmentBox.getYMin() + DbU::lambda(10.0) - , abutmentBox.getYMax() - DbU::lambda(10.0) - ); - NetExternalComponents::setExternal ( segment ); + NetExternalComponents::setExternal( segment ); } return master; @@ -140,76 +122,78 @@ namespace CRL { using Hurricane::Library; using Hurricane::Transformation; using Hurricane::UpdateSession; + using Utilities::Dots; Cell* Ispd05::load ( string benchmark ) { - AllianceFramework* af = AllianceFramework::get (); + AllianceFramework* af = AllianceFramework::get(); UpdateSession::open (); - auto_ptr circuit ( Bookshelf::Circuit::parse(benchmark) ); + auto_ptr circuit ( Bookshelf::Circuit::parse( benchmark + , Bookshelf::Circuit::AllSlots + , Bookshelf::Parser::NoFlags + ) ); - Cell* cell = af->createCell ( benchmark ); + cmess1 << " o Converting <" << benchmark << "> from Bookshelf to Hurricane." << endl; + Cell* cell = af->createCell( benchmark ); - addSupplyNets ( cell ); + addSupplyNets( cell ); - vector& nets = circuit->getNets (); - vector::iterator inet = nets.begin(); - for ( ; inet != nets.end() ; ++inet ) { - Net::create ( cell, (*inet)->getName() ); + Dots dots ( cmess2, " ", 80, 1000 ); + + cmess1 << " - Converting Nets." << endl; + for ( auto net : circuit->getNets() ) { + dots.dot(); + Net::create ( cell, net->getName() ); } + dots.finish( Dots::Reset|Dots::FirstDot ); - map& nodes = circuit->getNodes(); - map::iterator inode = nodes.begin(); + cmess1 << " - Converting Nodes." << endl; + for ( auto inode : circuit->getNodes() ) { + dots.dot(); + Bookshelf::Node* node = inode.second; - Box abutmentBox; - - for ( ; inode != nodes.end() ; ++inode ) { - Bookshelf::Node* node = (*inode).second; - - if ( node->isTerminal () ) continue; - Cell* master = toMasterCell ( af, node ); - - if ( master == NULL ) { - cerr << Warning("Skipping megacell <%s>.",node->getName().c_str()) << endl; + Cell* master = toMasterCell( af, node ); + if (master == NULL) { + cerr << Warning( "Skipping megacell <%s>.", node->getName().c_str() ) << endl; continue; } - Instance* instance = Instance::create ( cell, node->getName(), master ); + Instance* instance = Instance::create( cell, node->getName(), master ); - map& pins = node->getPins(); - map::iterator ipin = pins.begin(); - - for ( size_t pinnb=0 ; ipin != pins.end() ; ++ipin, ++pinnb ) { - Name netName ( (*ipin).second->getNet()->getName()); - Net* masterNet = master->getNet ( netName ); - instance->getPlug ( masterNet )->setNet ( cell->getNet(netName) ); - - DbU::Unit x = DbU::lambda( node->getX() * 5.0); - DbU::Unit y = DbU::lambda((node->getY()/16.0) * 50.0); - - if ( node->getOrientation() != Bookshelf::Orientation::N ) { - cerr << Warning("Skipping cell <%s>, unsupported orientation.",node->getName().c_str()) << endl; - continue; - } - - Box masterABox = master->getAbutmentBox(); - Transformation::Orientation orientation - = ( (int)(node->getY())%32 ) ? Transformation::Orientation::MY - : Transformation::Orientation::ID; - //Transformation::Orientation orientation = Transformation::Orientation::ID; - Transformation instanceTransformation = getTransformation(masterABox, x, y, orientation); - - instance->setTransformation ( instanceTransformation ); - instance->setPlacementStatus ( Instance::PlacementStatus::PLACED ); - - abutmentBox.merge ( instance->getAbutmentBox() ); + for ( auto ipin : node->getPins() ) { + Name netName = ipin.second->getNet()->getName(); + Net* masterNet = master->getNet( netName ); + instance->getPlug( masterNet )->setNet( cell->getNet(netName) ); } } - cell->setAbutmentBox ( abutmentBox ); + dots.finish( Dots::Reset|Dots::FirstDot ); - UpdateSession::close (); + // We assumes that the rows define a filled rectangular area. + cmess1 << " - Converting scl Rows." << endl; + dots.setDivider( 10 ); + Box abutmentBox; + for ( auto irow : circuit->getRows() ) { + dots.dot(); + + double x1 = (irow->getSubrowOrigin())*pitch; + double y1 = (irow->getCoordinate() )*pitch; + double x2 = (irow->getSitewidth()*irow->getNumsites())*pitch + x1; + double y2 = (irow->getHeight() )*pitch + y1; + + Box rowBox = Box( DbU::fromLambda(x1) + , DbU::fromLambda(y1) + , DbU::fromLambda(x2) + , DbU::fromLambda(y2) + ); + abutmentBox.merge( rowBox ); + } + cell->setAbutmentBox( abutmentBox ); + dots.finish( Dots::Reset|Dots::FirstDot ); + + UpdateSession::close(); return cell; } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 69bc1b2c..48969e74 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -17,8 +17,8 @@ #include #include #include -#include #include "coloquinte/circuit_graph.hxx" +#include "vlsisapd/utilities/Dots.h" #include "hurricane/DebugSession.h" #include "hurricane/Bug.h" #include "hurricane/Error.h" @@ -35,6 +35,7 @@ #include "hurricane/Horizontal.h" #include "hurricane/RoutingPad.h" #include "hurricane/UpdateSession.h" +#include "hurricane/viewer/CellWidget.h" #include "crlcore/Utilities.h" #include "crlcore/Measures.h" #include "crlcore/AllianceFramework.h" @@ -146,6 +147,7 @@ namespace Etesian { using std::pair; using std::make_pair; using std::unordered_map; + using Utilities::Dots; using Hurricane::DebugSession; using Hurricane::tab; using Hurricane::inltrace; @@ -163,11 +165,13 @@ namespace Etesian { using Hurricane::RoutingPad; using Hurricane::Net; using Hurricane::Occurrence; + using Hurricane::CellWidget; using CRL::ToolEngine; using CRL::AllianceFramework; using CRL::addMeasure; using CRL::Measures; using CRL::MeasuresSet; + using CRL::CatalogExtension; const char* missingEtesian = @@ -190,9 +194,12 @@ namespace Etesian { EtesianEngine::EtesianEngine ( Cell* cell ) - : ToolEngine (cell) - , _circuit (NULL) - , _cellsToIds() + : ToolEngine (cell) + , _configuration(NULL) + , _flags (0) + , _circuit (NULL) + , _cellsToIds () + , _cellWidget (NULL) { } @@ -236,10 +243,62 @@ namespace Etesian { { return _configuration; } + void EtesianEngine::resetPlacement () + { + //cerr << "EtesianEngine::resetPlacement()" << endl; + + if (_flags & NoPlacement) return; + _flags |= FlatDesign; + + //getCell()->flattenNets( true ); + + Dots dots ( cmess2, " ", 80, 1000 ); + + cmess1 << " o Erasing previous placement of <" << getCell()->getName() << ">" << endl; + + UpdateSession::open(); + vector feedOccurrences; + forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) + { + dots.dot(); + + if ((_flags & FlatDesign) and not (*ioccurrence).getPath().getTailPath().isEmpty()) + _flags &= ~FlatDesign; + + Instance* instance = static_cast((*ioccurrence).getEntity()); + Cell* masterCell = instance->getMasterCell(); + string instanceName = (*ioccurrence).getCompactString(); + + if (CatalogExtension::isFeed(masterCell)) { + feedOccurrences.push_back( *ioccurrence ); + } + } + + for ( auto ioccurrence : feedOccurrences ) { + cerr << " Destroy: " << ioccurrence.getCompactString() << endl; + Instance* instance = static_cast(ioccurrence.getEntity()); + instance->destroy(); + } + UpdateSession::close(); + + dots.finish( Dots::Reset ); + + if (_cellWidget) _cellWidget->refresh(); + + _flags |= NoPlacement; + } + + void EtesianEngine::place ( unsigned int slowMotion ) { - AllianceFramework* af = AllianceFramework::get(); + cmess1 << " o Converting <" << getCell()->getName() << "> into Coloquinte." << endl; + resetPlacement(); + + Dots dots ( cmess2, " ", 80, 1000 ); + AllianceFramework* af = AllianceFramework::get(); + + cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; getCell()->flattenNets( true ); // Coloquinte circuit description data-structures. @@ -247,6 +306,9 @@ namespace Etesian { _circuit->cells .resize( getCell()->getLeafInstanceOccurrences().getSize() ); _circuit->hypernets.resize( getCell()->getNets().getSize() ); + cmess1 << " - Converting Instances (Bookshelf nodes)" << endl; + cout.flush(); + Coloquinte::cell_id cellId = 0; forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) { @@ -257,12 +319,16 @@ namespace Etesian { instanceName.erase( 0, 1 ); instanceName.erase( instanceName.size()-1 ); - cerr << instanceName << " " << (int)instance->getPlacementStatus().getCode() << endl; + if (CatalogExtension::isFeed(masterCell)) continue; - Coloquinte::circuit_coordinate cellSize ( DbU::toLambda( masterCell->getAbutmentBox().getWidth () ) - , DbU::toLambda( masterCell->getAbutmentBox().getHeight() )); + Coloquinte::circuit_coordinate cellSize ( masterCell->getAbutmentBox().getWidth () / DbU::fromLambda(5.0) + , masterCell->getAbutmentBox().getHeight() / DbU::fromLambda(5.0) ); _cellsToIds.insert( make_pair(instanceName,cellId) ); + dots.dot(); + //cerr << instanceName << " " << (int)instance->getPlacementStatus().getCode() + // << " area:" << cellSize.cast().prod() << endl; + _circuit->cells[cellId].name = instanceName; _circuit->cells[cellId].sizes = cellSize; _circuit->cells[cellId].area = cellSize.cast().prod(); @@ -271,6 +337,9 @@ namespace Etesian { cellId++; } + dots.finish( Dots::Reset|Dots::FirstDot ); + + cmess1 << " - Converting Nets (Bookshelf nets)" << endl; unsigned int netId = 0; forEach ( Net*, inet, getCell()->getNets() ) @@ -286,14 +355,16 @@ namespace Etesian { } if (af->isBLOCKAGE((*inet)->getName())) continue; - cerr << (*inet)->getName() << endl; + dots.dot(); + //cerr << (*inet)->getName() << endl; + forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { - cerr << " " << (*irp)->getOccurrence().getCompactString() << endl; + //cerr << " " << (*irp)->getOccurrence().getCompactString() << endl; string insName = extractInstanceName( *irp ); Point offset = extractRpOffset ( *irp ); - cerr << " Master Cell: " << (*irp)->getOccurrence().getMasterCell() << endl; - cerr << " Rebuilt instance name: " << insName << " " << offset << endl; + //cerr << " Master Cell: " << (*irp)->getOccurrence().getMasterCell() << endl; + //cerr << " Rebuilt instance name: " << insName << " " << offset << endl; auto iid = _cellsToIds.find( insName ); if (iid == _cellsToIds.end() ) { @@ -307,8 +378,8 @@ namespace Etesian { Coloquinte::cell::pin cellPin; //cellPin.name = extractTerminalName( *irp ); cellPin.d = extractDirection ( *irp ); - cellPin.offs.x() = DbU::toLambda( offset.getX() ); - cellPin.offs.y() = DbU::toLambda( offset.getY() ); + cellPin.offs.x() = offset.getX() / DbU::fromLambda(5.0); + cellPin.offs.y() = offset.getY() / DbU::fromLambda(5.0); cellPin.ind = cellPinId; _circuit->cells[cellId].pins.push_back( cellPin ); } @@ -316,6 +387,7 @@ namespace Etesian { netId++; } + dots.finish( Dots::Reset ); _circuit->position_overlays.resize(1); _circuit->position_overlays[0].x_pos = Coloquinte::circuit_vector( _cellsToIds.size() ); @@ -329,36 +401,60 @@ namespace Etesian { } _circuit->bounds = Coloquinte::circuit_box - ( Coloquinte::circuit_coordinate::Zero() - , Coloquinte::circuit_coordinate( { DbU::toLambda(getCell()->getAbutmentBox().getWidth ()) - , DbU::toLambda(getCell()->getAbutmentBox().getHeight()) } )); + ( Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMin() / DbU::fromLambda(5.0) + , getCell()->getAbutmentBox().getYMin() / DbU::fromLambda(5.0) } ) + , Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMax() / DbU::fromLambda(5.0) + , getCell()->getAbutmentBox().getYMax() / DbU::fromLambda(5.0) } )); - float strength, strength_incr; + _circuit->selfcheck(); - cout << "Initial placement at " << time(NULL) << endl; - for(int j = 0; j < 3; j++){ + cmess1 << " o Running Coloquinte." << endl; + cmess1 << " - Computing initial placement..." << endl; + cmess2 << setfill('0') << right; + + time_t startTime = time(NULL); + time_t timeDelta; + Coloquinte::circuit_scalar upperBound; + Coloquinte::circuit_scalar lowerBound; + + for ( int j = 0; j < 3; j++ ) { _circuit->position_overlays[0] = Coloquinte::solve_quadratic_model( *_circuit , _circuit->position_overlays[0] , _circuit->position_overlays[0] ); - cout << "At " << time(NULL) << ", lower bound is " - << B2B_wirelength(*_circuit, _circuit->position_overlays[0]) << endl; + + timeDelta = time(NULL) - startTime; + lowerBound = B2B_wirelength( *_circuit, _circuit->position_overlays[0] ); + cmess2 << " Iteration " << setw( 4) << (j+1) + << " Elapsed time:" << setw( 5) << timeDelta << "s" + << " Lower bound:" << setw(10) + << lowerBound << endl; + + _updatePlacement( 0 ); } - strength = 0.000001; - strength_incr = 0.000002; + float strength = 0.000001; + float strength_incr = 0.000002; + + cmess1 << " - Optimizing placement..." << endl; _circuit->position_overlays.resize(2); - for(int j = 0; j < 200; j++, strength = strength * 1.02 + strength_incr){ + for ( int j = 0; j < 200; j++, strength = strength * 1.02 + strength_incr) { _circuit->position_overlays[1] = Coloquinte::legalize( *_circuit , 1.0 , _circuit->position_overlays[0] + , 1 , false ); - cout << "At " << time(NULL) << " and iteration " << j - << ", upper bound is " << /*B2B_wirelength(*_circuit, _circuit->position_overlays[1]) <<*/ endl; + + timeDelta = time(NULL) - startTime; + upperBound = B2B_wirelength( *_circuit, _circuit->position_overlays[1] ); + cmess2 << " Iteration " << setw( 4) << (j+1) + << " Elapsed time:" << setw( 5) << timeDelta << "s" + << " UPPER bound:" << setw(10) + << upperBound << endl; _circuit->position_overlays[0] = Coloquinte::solve_quadratic_model( *_circuit @@ -366,15 +462,24 @@ namespace Etesian { , _circuit->position_overlays[1] , strength ); - cout << "At " << time(NULL) << " and iteration " << j - << ", lower bound is " << /*B2B_wirelength(*_circuit, _circuit->position_overlays[0]) <<*/ endl; + timeDelta = time(NULL) - startTime; + lowerBound = B2B_wirelength( *_circuit, _circuit->position_overlays[0] ); + cmess2 << " " + << " Elapsed time:" << setw( 5) << timeDelta << "s" + << " Lower bound:" << setw(10) + << lowerBound << endl; + cmess2 << " Spreading ratio: " + << ((((double)upperBound-(double)lowerBound)*100) / (double)lowerBound) << "%" << endl; + + _updatePlacement( 0 ); } - _updatePlacement(); + _updatePlacement( 1 ); + _flags &= ~NoPlacement; } - void EtesianEngine::_updatePlacement () + void EtesianEngine::_updatePlacement ( unsigned int placementId ) { UpdateSession::open(); @@ -392,18 +497,21 @@ namespace Etesian { if (iid == _cellsToIds.end() ) { cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl; } else { - instancePosition.setX( DbU::fromLambda(_circuit->position_overlays[0].x_pos[(*iid).second]) ); - instancePosition.setY( DbU::fromLambda(_circuit->position_overlays[0].y_pos[(*iid).second]) ); + instancePosition.setX( _circuit->position_overlays[placementId].x_pos[(*iid).second] * DbU::fromLambda(5.0) ); + instancePosition.setY( _circuit->position_overlays[placementId].y_pos[(*iid).second] * DbU::fromLambda(5.0) ); - cerr << "Setting <" << instanceName << " @" << instancePosition << endl; + //cerr << "Setting <" << instanceName << " @" << instancePosition << endl; // This is temporary as it's not trans-hierarchic: we ignore the posutions // of all the intermediary instances. instance->setTransformation( instancePosition ); + instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); } } UpdateSession::close(); + + if (_cellWidget) _cellWidget->refresh(); } diff --git a/etesian/src/GraphicEtesianEngine.cpp b/etesian/src/GraphicEtesianEngine.cpp index d665ee35..1b9a7f24 100644 --- a/etesian/src/GraphicEtesianEngine.cpp +++ b/etesian/src/GraphicEtesianEngine.cpp @@ -65,6 +65,7 @@ namespace Etesian { EtesianEngine* etesian = EtesianEngine::get( cell ); if (not etesian) { etesian = EtesianEngine::create( cell ); + etesian->setCellWidget( _viewer->getCellWidget() ); } else cerr << Warning( "%s already has a Etesian engine.", getString(cell).c_str() ) << endl; @@ -99,6 +100,10 @@ namespace Etesian { emit cellPreModificated(); _viewer->clearToolInterrupt(); + etesian->resetPlacement(); + emit cellPostModificated(); + + emit cellPostModificated(); etesian->place(); emit cellPostModificated(); } diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index 5699c129..be17f72c 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -30,6 +30,7 @@ namespace Hurricane { class Layer; class Net; class Cell; + class CellWidget; } #include "crlcore/ToolEngine.h" @@ -49,7 +50,8 @@ namespace Etesian { // Class : "Etesian::EtesianEngine". class EtesianEngine : public CRL::ToolEngine { - + public: + enum Flag { NoPlacement=0x0001, FlatDesign=0x0002 }; public: static const Name& staticGetName (); static EtesianEngine* create ( Cell* ); @@ -57,8 +59,10 @@ namespace Etesian { public: virtual Configuration* getConfiguration (); virtual const Name& getName () const; + inline void setCellWidget ( Hurricane::CellWidget* ); + void resetPlacement (); void place ( unsigned int slowMotion=0 ); - void _updatePlacement (); + void _updatePlacement ( unsigned int placementId ); virtual Record* _getRecord () const; virtual std::string _getString () const; virtual std::string _getTypeName () const; @@ -68,8 +72,10 @@ namespace Etesian { static Name _toolName; protected: Configuration* _configuration; + unsigned int _flags; Coloquinte::circuit* _circuit; std::unordered_map _cellsToIds; + Hurricane::CellWidget* _cellWidget; protected: // Constructors & Destructors. @@ -84,6 +90,7 @@ namespace Etesian { // Inline Functions. + inline void EtesianEngine::setCellWidget ( Hurricane::CellWidget* cw ) { _cellWidget = cw; } // Variables. diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 8181fd80..ba45e746 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -216,7 +216,7 @@ void Cell::flattenNets(bool buildRings) } forEach ( Occurrence, iplugOccurrence, hyperNet.getLeafPlugOccurrences() ) { - currentRP = RoutingPad::create ( net, *iplugOccurrence, RoutingPad::BiggestArea|RoutingPad::ShowWarning ); + currentRP = RoutingPad::create ( net, *iplugOccurrence, RoutingPad::BiggestArea/*|RoutingPad::ShowWarning*/ ); currentRP->materialize (); if ( buildRings ) { if ( previousRP ) { diff --git a/unicorn/src/CMakeLists.txt b/unicorn/src/CMakeLists.txt index 0851be62..d8db0188 100644 --- a/unicorn/src/CMakeLists.txt +++ b/unicorn/src/CMakeLists.txt @@ -47,6 +47,8 @@ ${KATABATIC_LIBRARIES} ${KNIK_GRAPHICAL_LIBRARIES} ${KNIK_LIBRARIES} + ${ETESIAN_GRAPHICAL_LIBRARIES} + ${ETESIAN_LIBRARIES} ${MAUKA_GRAPHICAL_LIBRARIES} ${MAUKA_LIBRARIES} ${METIS_LIBRARIES} diff --git a/unicorn/src/CgtMain.cpp b/unicorn/src/CgtMain.cpp index 8a7bb568..a05930e1 100644 --- a/unicorn/src/CgtMain.cpp +++ b/unicorn/src/CgtMain.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -65,6 +65,9 @@ using namespace Metis; #include "mauka/GraphicMaukaEngine.h" using namespace Mauka; +#include "etesian/GraphicEtesianEngine.h" +using namespace Etesian; + #include "knik/GraphicKnikEngine.h" using namespace Knik; @@ -326,6 +329,7 @@ int main ( int argc, char *argv[] ) unicorn->setApplicationName ( QObject::tr("cgt") ); unicorn->registerTool ( Mauka::GraphicMaukaEngine::grab() ); + unicorn->registerTool ( Etesian::GraphicEtesianEngine::grab() ); //unicorn->registerTool ( Knik::GraphicKnikEngine::grab() ); unicorn->registerTool ( Kite::GraphicKiteEngine::grab() ); //unicorn->setEnableRedrawInterrupt ( true ); diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index 5661ea29..c0815875 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -198,7 +198,6 @@ namespace Unicorn { break; case ImportCellDialog::Ispd05: cell = Ispd05::load ( cellName.toStdString() ); - cerr << "Cell " << " successfully loaded." << endl; break; case ImportCellDialog::Iccad04: cell = Iccad04Lefdef::load ( cellName.toStdString() , 0 ); @@ -214,7 +213,6 @@ namespace Unicorn { viewer = UnicornGui::create (); viewer->show (); } - cerr << "Loading " << cell->getName() << " into the viewer." << endl; viewer->setCell ( cell ); } else cerr << "[ERROR] Cell not found: " << cellName.toStdString() << endl; diff --git a/vlsisapd/src/bookshelf/src/Bookshelf.cpp b/vlsisapd/src/bookshelf/src/Bookshelf.cpp index dfe579b2..503f42a4 100644 --- a/vlsisapd/src/bookshelf/src/Bookshelf.cpp +++ b/vlsisapd/src/bookshelf/src/Bookshelf.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | V L S I Stand - Alone Parsers / Drivers | diff --git a/vlsisapd/src/bookshelf/src/Circuit.cpp b/vlsisapd/src/bookshelf/src/Circuit.cpp index cdb08ca2..f7475a09 100644 --- a/vlsisapd/src/bookshelf/src/Circuit.cpp +++ b/vlsisapd/src/bookshelf/src/Circuit.cpp @@ -86,10 +86,10 @@ namespace Bookshelf { { _rows.push_back ( row ); } - Circuit* Circuit::parse ( std::string auxFile, unsigned int flags ) + Circuit* Circuit::parse ( std::string auxFile, unsigned int slots, unsigned int flags ) { Parser parser; - return parser.parse ( auxFile, flags ); + return parser.parse ( auxFile, slots, flags ); } @@ -214,14 +214,14 @@ namespace Bookshelf { } - void Circuit::drive ( std::string directory, unsigned int flags ) + void Circuit::drive ( std::string directory, unsigned int slots ) { Utilities::Path rootDirectory ( directory ); if ( not rootDirectory.exists() ) { rootDirectory.mkdir(); } - if ( flags & Nodes ) { + if ( slots & Nodes ) { Utilities::Path nodesPath ( rootDirectory ); if ( getNodesName().empty() ) nodesPath /= getDesignName() + ".nodes"; @@ -233,7 +233,7 @@ namespace Bookshelf { ofnodes.close (); } - if ( flags & Nets ) { + if ( slots & Nets ) { Utilities::Path netsPath ( rootDirectory ); if ( getNetsName().empty() ) netsPath /= getDesignName() + ".nets"; @@ -245,7 +245,7 @@ namespace Bookshelf { ofnets.close (); } - if ( (flags & Scl) and (hasScl()) ) { + if ( (slots & Scl) and (hasScl()) ) { Utilities::Path sclPath ( rootDirectory ); if ( getSclName().empty() ) sclPath /= getDesignName() + ".scl"; @@ -257,7 +257,7 @@ namespace Bookshelf { ofscl.close (); } - if ( (flags & Pl) and (hasPl()) ) { + if ( (slots & Pl) and (hasPl()) ) { Utilities::Path plPath ( rootDirectory ); if ( getPlName().empty() ) plPath /= getDesignName() + ".pl"; diff --git a/vlsisapd/src/bookshelf/src/Parser.cpp b/vlsisapd/src/bookshelf/src/Parser.cpp index 8239d199..2bac4bfd 100644 --- a/vlsisapd/src/bookshelf/src/Parser.cpp +++ b/vlsisapd/src/bookshelf/src/Parser.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | V L S I Stand - Alone Parsers / Drivers | @@ -15,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include #include #include "vlsisapd/bookshelf/Exception.h" #include "vlsisapd/bookshelf/Node.h" @@ -71,7 +71,7 @@ namespace Bookshelf { , _stream () , _buffer () , _tokens () - , _flags (0) + , _flags (StrictSyntax) , _state (0) , _net (NULL) , _row (NULL) @@ -151,11 +151,25 @@ namespace Bookshelf { } + int Parser::_keywordCompare ( const string& a, const string& b ) const + { + if (_flags & StrictSyntax) return a.compare(b); + + string lowerA = a; + string lowerB = b; + + for ( size_t i=0 ; i slot.",slotName.c_str()); } @@ -165,9 +179,9 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 3 ) - or ( token.compare(_tokens[0]) != 0) - or (std::string(":" ).compare(_tokens[1]) != 0) ) - throw Exception("Bookshelf::Parse(): @%d, Invalid %s in <.%s>.",_lineno, token.c_str(),slotName.c_str()); + or (_keywordCompare(token,_tokens[0]) != 0) + or (_keywordCompare(":" ,_tokens[1]) != 0) ) + throw Exception("Bookshelf::Parse(): @%d, Invalid %s in XX <.%s>.",_lineno, token.c_str(),slotName.c_str()); //std::cerr << _tokens.size() << ":" << _tokens[2] << ":" << _circuit->getNumNodes() << std::endl; @@ -193,13 +207,13 @@ namespace Bookshelf { for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) { //std::cerr << "F:" << _tokens[itoken] << " "; if ( symmetryTokens ) { - if ( std::string("X" ).compare(_tokens[itoken]) == 0 ) { symmetry |= Symmetry::X; continue; } - if ( std::string("Y" ).compare(_tokens[itoken]) == 0 ) { symmetry |= Symmetry::Y; continue; } - if ( std::string("R90").compare(_tokens[itoken]) == 0 ) { symmetry |= Symmetry::R90; continue; } + if ( _keywordCompare("X" ,_tokens[itoken]) == 0 ) { symmetry |= Symmetry::X; continue; } + if ( _keywordCompare("Y" ,_tokens[itoken]) == 0 ) { symmetry |= Symmetry::Y; continue; } + if ( _keywordCompare("R90",_tokens[itoken]) == 0 ) { symmetry |= Symmetry::R90; continue; } symmetryTokens = false; } - if ( std::string("terminal").compare(_tokens[itoken]) == 0 ) { terminal = true; continue; } - if ( std::string(":").compare(_tokens[itoken]) == 0 ) { symmetryTokens = true; continue; } + if ( _keywordCompare("terminal",_tokens[itoken]) == 0 ) { terminal = true; continue; } + if ( _keywordCompare(":" ,_tokens[itoken]) == 0 ) { symmetryTokens = true; continue; } //std::cerr << " " << std::endl; @@ -261,8 +275,8 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 3 ) - or (std::string("NetDegree").compare(_tokens[0]) != 0) - or (std::string(":" ).compare(_tokens[1]) != 0) ) + or (_keywordCompare("NetDegree",_tokens[0]) != 0) + or (_keywordCompare(":" ,_tokens[1]) != 0) ) throw Exception("Bookshelf::Parse(): @%d, Invalid NetDegree in <.nets>.",_lineno); std::string name; @@ -286,16 +300,16 @@ namespace Bookshelf { for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) { //std::cerr << "F:" << _tokens[itoken] << " "; if ( tokenDirection ) { - if ( std::string("I").compare(_tokens[itoken]) == 0 ) { direction |= Direction::Input; } - if ( std::string("O").compare(_tokens[itoken]) == 0 ) { direction |= Direction::Output; } - if ( std::string("B").compare(_tokens[itoken]) == 0 ) { direction |= Direction::Bidirectional; } + if ( _keywordCompare("I",_tokens[itoken]) == 0 ) { direction |= Direction::Input; } + if ( _keywordCompare("O",_tokens[itoken]) == 0 ) { direction |= Direction::Output; } + if ( _keywordCompare("B",_tokens[itoken]) == 0 ) { direction |= Direction::Bidirectional; } if ( direction != Direction::Disabled ) { tokenDirection = false; continue; } } - if ( std::string(":").compare(_tokens[itoken]) == 0 ) { + if ( _keywordCompare(":",_tokens[itoken]) == 0 ) { tokenDirection = false; if ( ++itoken == _tokens.size() ) @@ -382,8 +396,8 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 2) - or (std::string("CoreRow" ).compare(_tokens[0]) != 0) - or (std::string("Horizontal").compare(_tokens[1]) != 0) ) + or (_keywordCompare("CoreRow" ,_tokens[0]) != 0) + or (_keywordCompare("Horizontal",_tokens[1]) != 0) ) throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow line in <.scl>.",_lineno); _row = new Row (); @@ -396,20 +410,22 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 3) - or (std::string("Siteorient").compare(_tokens[0]) != 0) - or (std::string(":" ).compare(_tokens[1]) != 0) ) - throw Exception("Bookshelf::Parse(): @%d, Invalid Row siteorient line in <.scl>.",_lineno); + or (_keywordCompare("Siteorient",_tokens[0]) != 0) + or (_keywordCompare(":" ,_tokens[1]) != 0) ) + throw Exception("Bookshelf::Parse(): @%d, Invalid Row XX siteorient line in <.scl>.",_lineno); - if ( std::string("N" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::N); } - else if ( std::string("E" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::E); } - else if ( std::string("S" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::S); } - else if ( std::string("W" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::W); } - else if ( std::string("FN").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FN); } - else if ( std::string("FE").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FE); } - else if ( std::string("FS").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FS); } - else if ( std::string("FW").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FW); } - else - throw Exception("Bookshelf::Parse(): @%d, Invalid Row siteorient line in <.scl>.",_lineno); + if ( _keywordCompare("N" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::N); } + else if ( _keywordCompare("E" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::E); } + else if ( _keywordCompare("S" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::S); } + else if ( _keywordCompare("W" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::W); } + else if ( _keywordCompare("FN",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FN); } + else if ( _keywordCompare("FE",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FE); } + else if ( _keywordCompare("FS",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FS); } + else if ( _keywordCompare("FW",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FW); } + else { + //throw Exception("Bookshelf::Parse(): @%d, Invalid Row siteorient line in <.scl>.",_lineno); + _row->setSiteorient(Orientation::N); + } } @@ -418,15 +434,17 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 3) - or (std::string("Sitesymmetry").compare(_tokens[0]) != 0) - or (std::string(":" ).compare(_tokens[1]) != 0) ) + or (_keywordCompare("Sitesymmetry",_tokens[0]) != 0) + or (_keywordCompare(":" ,_tokens[1]) != 0) ) throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno); - if ( std::string("X" ).compare(_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::X); } - else if ( std::string("Y" ).compare(_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::Y); } - else if ( std::string("R90").compare(_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::R90); } - else - throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno); + if ( _keywordCompare("X" ,_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::X); } + else if ( _keywordCompare("Y" ,_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::Y); } + else if ( _keywordCompare("R90",_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::R90); } + else { + _row->setSitesymmetry(Symmetry::X); + //throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno); + } } @@ -435,10 +453,10 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 6) - or (std::string("SubrowOrigin").compare(_tokens[0]) != 0) - or (std::string(":" ).compare(_tokens[1]) != 0) - or (std::string("Numsites" ).compare(_tokens[3]) != 0) - or (std::string(":" ).compare(_tokens[4]) != 0) ) + or (_keywordCompare("SubrowOrigin",_tokens[0]) != 0) + or (_keywordCompare(":" ,_tokens[1]) != 0) + or (_keywordCompare("Numsites" ,_tokens[3]) != 0) + or (_keywordCompare(":" ,_tokens[4]) != 0) ) throw Exception("Bookshelf::Parse(): @%d, Invalid Row SubrowOrigin line in <.scl>.",_lineno); _row->setSubrowOrigin ( toDouble(_tokens[2]) ); @@ -451,7 +469,7 @@ namespace Bookshelf { _tokenize (); if ( (_tokens.size() < 1) - or (std::string("End").compare(_tokens[0]) != 0) ) + or (_keywordCompare("End",_tokens[0]) != 0) ) throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow end line in <.scl>.",_lineno); _row = NULL; @@ -526,17 +544,17 @@ namespace Bookshelf { for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) { //std::cerr << "F:" << _tokens[itoken] << " "; if ( orientationToken ) { - if ( std::string("N" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::N; continue; } - if ( std::string("E" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::E; continue; } - if ( std::string("S" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::S; continue; } - if ( std::string("W" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::W; continue; } - if ( std::string("FN").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FN; continue; } - if ( std::string("FE").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FE; continue; } - if ( std::string("FS").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FS; continue; } - if ( std::string("FW").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FW; continue; } + if ( _keywordCompare("N" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::N; continue; } + if ( _keywordCompare("E" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::E; continue; } + if ( _keywordCompare("S" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::S; continue; } + if ( _keywordCompare("W" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::W; continue; } + if ( _keywordCompare("FN",_tokens[itoken]) == 0 ) { orientation |= Orientation::FN; continue; } + if ( _keywordCompare("FE",_tokens[itoken]) == 0 ) { orientation |= Orientation::FE; continue; } + if ( _keywordCompare("FS",_tokens[itoken]) == 0 ) { orientation |= Orientation::FS; continue; } + if ( _keywordCompare("FW",_tokens[itoken]) == 0 ) { orientation |= Orientation::FW; continue; } break; } - if ( std::string(":").compare(_tokens[itoken]) == 0 ) { orientationToken = true; continue; } + if ( _keywordCompare(":",_tokens[itoken]) == 0 ) { orientationToken = true; continue; } //std::cerr << " " << std::endl; @@ -580,8 +598,10 @@ namespace Bookshelf { } - Circuit* Parser::parse ( std::string designName, unsigned int flags ) + Circuit* Parser::parse ( std::string designName, unsigned int slots, unsigned int flags ) { + _flags = flags; + Utilities::Path auxPath ( designName+".aux" ); if ( not auxPath.exists() ) { throw Exception ( "%s .aux file not found.", auxPath.string().c_str() ); @@ -597,7 +617,7 @@ namespace Bookshelf { _closeStream (); _tokenize (); - if ( std::string(":").compare(_tokens[1]) == 0 ) { + if ( _keywordCompare(":",_tokens[1]) == 0 ) { // Re-ordering files: .nodes, .nets, .wts, .scl, .pl. std::string ordereds [5]; @@ -608,23 +628,23 @@ namespace Bookshelf { switch ( extension ) { case 0: - if ( (file.compare(iext,6,".nodes") == 0) and (flags & Circuit::Nodes) ) + if ( (file.compare(iext,6,".nodes") == 0) and (slots & Circuit::Nodes) ) ordereds[0] = _tokens[i]; break; case 1: - if ( (file.compare(iext,5,".nets") == 0) and (flags & Circuit::Nets) ) + if ( (file.compare(iext,5,".nets") == 0) and (slots & Circuit::Nets) ) ordereds[1] = _tokens[i]; break; case 2: - if ( (file.compare(iext,4,".wts") == 0) and (flags & Circuit::Wts) ) + if ( (file.compare(iext,4,".wts") == 0) and (slots & Circuit::Wts) ) ordereds[2] = _tokens[i]; break; case 3: - if ( (file.compare(iext,4,".scl") == 0) and (flags & Circuit::Scl) ) + if ( (file.compare(iext,4,".scl") == 0) and (slots & Circuit::Scl) ) ordereds[3] = _tokens[i]; break; case 4: - if ( (file.compare(iext,3,".pl") == 0) and (flags & Circuit::Pl) ) + if ( (file.compare(iext,3,".pl") == 0) and (slots & Circuit::Pl) ) ordereds[4] = _tokens[i]; break; } @@ -643,7 +663,7 @@ namespace Bookshelf { Utilities::Path slotPath ( ordereds[iext] ); if ( slotPath.exists() ) { - std::cout << " o Reading <" << slotPath.string() << ">" << std::endl; + std::cout << " - Reading <" << slotPath.string() << ">" << std::endl; switch ( iext ) { case 0: _parseNodes ( slotPath ); break; diff --git a/vlsisapd/src/bookshelf/src/Pin.cpp b/vlsisapd/src/bookshelf/src/Pin.cpp index 6472ef9f..f22f44a4 100644 --- a/vlsisapd/src/bookshelf/src/Pin.cpp +++ b/vlsisapd/src/bookshelf/src/Pin.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | B o o k s h e l f P a r s e r | // | | @@ -17,10 +11,7 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./Pin.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include "vlsisapd/bookshelf/Node.h" diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h index e8b89c54..63462cca 100644 --- a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // -// This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// This file is part of the VLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | B o o k s h e l f P a r s e r | // | | @@ -17,14 +11,11 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./bookshelf/Circuit.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __VLSISAPD_BOOKSHELF_CIRCUIT__ -#define __VLSISAPD_BOOKSHELF_CIRCUIT__ +#ifndef VLSISAPD_BOOKSHELF_CIRCUIT_H +#define VLSISAPD_BOOKSHELF_CIRCUIT_H #include #include @@ -44,10 +35,11 @@ namespace Bookshelf { enum Slot { Nets=0x1, Nodes=0x2, Wts=0x4, Scl=0x8, Pl=0x10, AllSlots=Nodes|Nets|Wts|Scl|Pl }; public: static Circuit* parse ( std::string design - , unsigned int flags =AllSlots + , unsigned int slots =AllSlots + , unsigned int flags =0 ); void drive ( std::string directory - , unsigned int flags =AllSlots + , unsigned int slots =AllSlots ); public: Circuit (); @@ -154,5 +146,4 @@ namespace Bookshelf { } // End of Bookshelf namespace. - -#endif // __VLSISAPD_BOOKSHELF_CIRCUIT__ +#endif // VLSISAPD_BOOKSHELF_CIRCUIT_H diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h index 7687c4d6..85c7703d 100644 --- a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | B o o k s h e l f P a r s e r | // | | @@ -17,14 +11,11 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./bookshelf/Node.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __VLSISAPD_BOOKSHELF_NODE__ -#define __VLSISAPD_BOOKSHELF_NODE__ +#ifndef VLSISAPD_BOOKSHELF_NODE_H +#define VLSISAPD_BOOKSHELF_NODE_H #include #include diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h index a3325dbe..da68c3f6 100644 --- a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // -// This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// This file is part of the VLSI Stand-Alone Software. +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | V L S I Stand - Alone Parsers / Drivers | @@ -27,18 +26,28 @@ namespace Bookshelf { + class Row; class Parser { public: - enum Flag { Comment=0x1, ExtraDatas=0x2 }; + enum Flag { NoFlags = 0x0000 + , Comment = 0x0001 + , ExtraDatas = 0x0002 + , StrictSyntax = 0x0004 + }; public: Parser (); - Circuit* parse ( std::string designName, unsigned int flags ); + Circuit* parse ( std::string designName + , unsigned int slots + , unsigned int flags ); + inline void setFlags ( unsigned int flags ); + inline void unsetFlags ( unsigned int flags ); private: bool _openStream ( const Utilities::Path& ); void _closeStream (); char* _readLine (); void _tokenize (); + int _keywordCompare ( const std::string&, const std::string& ) const; void _checkExtraDatas ( size_t maxtoken, std::vector& ); void _parseFormatRevision ( const std::string& slotName ); size_t _parseNum ( const std::string& slotName, const std::string& token ); @@ -73,6 +82,8 @@ namespace Bookshelf { }; + inline void Parser::setFlags ( unsigned int flags ) { _flags |= flags; } + inline void Parser::unsetFlags ( unsigned int flags ) { _flags &= ~flags; } inline bool Parser::_isComment () const { return _flags&Comment; } inline bool Parser::_hasExtraDatas () const { return _flags&ExtraDatas; } diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h index 6a51acae..4223647a 100644 --- a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h @@ -1,30 +1,21 @@ - // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | B o o k s h e l f P a r s e r | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./bookshelf/Pin.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./vlsisapd/bookshelf/Pin.h" | +// +-----------------------------------------------------------------+ -#ifndef __VLSISAPD_BOOKSHELF_PIN__ -#define __VLSISAPD_BOOKSHELF_PIN__ +#ifndef VLSISAPD_BOOKSHELF_PIN_H +#define VLSISAPD_BOOKSHELF_PIN_H #include #include @@ -78,7 +69,6 @@ namespace Bookshelf { inline Node* Pin::getNode () const { return _node; } -} // End of Bookshelf namespace. +} // Bookshelf namespace. - -#endif // __VLSISAPD_BOOKSHELF_PIN__ +#endif // VLSISAPD_BOOKSHELF_PIN_H diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h index 12f3ec1a..e4d2e2e4 100644 --- a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // -// This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// This file is part of the VLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | B o o k s h e l f P a r s e r | // | | @@ -17,14 +11,11 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./bookshelf/Row.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __VLSISAPD_BOOKSHELF_ROW__ -#define __VLSISAPD_BOOKSHELF_ROW__ +#ifndef VLSISAPD_BOOKSHELF_ROW_H +#define VLSISAPD_BOOKSHELF_ROW_H #include #include diff --git a/vlsisapd/src/utilities/src/CMakeLists.txt b/vlsisapd/src/utilities/src/CMakeLists.txt index cb95231e..bd6cf1ab 100644 --- a/vlsisapd/src/utilities/src/CMakeLists.txt +++ b/vlsisapd/src/utilities/src/CMakeLists.txt @@ -3,11 +3,13 @@ include_directories ( ${VLSISAPD_SOURCE_DIR}/src/utilities/src ) - set ( includes vlsisapd/utilities/Path.h - ) - set ( cpps Path.cpp - ) - + set ( includes vlsisapd/utilities/Path.h + vlsisapd/utilities/Dots.h + ) + set ( cpps Path.cpp + Dots.cpp + ) + add_library ( vlsisapdutils ${cpps} ) set_target_properties ( vlsisapdutils PROPERTIES VERSION 1.0 SOVERSION 1 ) diff --git a/vlsisapd/src/utilities/src/Dots.cpp b/vlsisapd/src/utilities/src/Dots.cpp new file mode 100644 index 00000000..e204791e --- /dev/null +++ b/vlsisapd/src/utilities/src/Dots.cpp @@ -0,0 +1,53 @@ +// -*- C++ -*- +// +// This file is part of the VLSI Stand-Alone Software. +// Copyright (c) UPMC 2013-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | V L S I Stand - Alone Parsers / Drivers | +// | M i s c e l l a n e o u s U t i l i t i e s | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Dots.cpp" | +// +-----------------------------------------------------------------+ + + +#include "vlsisapd/utilities/Dots.h" + + +namespace Utilities { + + + void Dots::dot () + { + ++_count; + if (_count % _divider == 0) { + unsigned int position = _count / _divider; + if (position == 1) { + if (not (_flags & FirstDot)) + CR(); + else + _flags &= ~FirstDot; + _ostream << _indent; + } + + _flush( '.' ); + + if (position + _indent.size() >= _width) { + reset( NoFlags ); + } + } + } + + + void Dots::finish ( unsigned int flags ) + { + CR(); + + if (flags & Reset) reset( flags ); + } + + +} // Utilities namespace. diff --git a/vlsisapd/src/utilities/src/Path.cpp b/vlsisapd/src/utilities/src/Path.cpp index a8d50c56..32b774fc 100644 --- a/vlsisapd/src/utilities/src/Path.cpp +++ b/vlsisapd/src/utilities/src/Path.cpp @@ -1,7 +1,6 @@ - // -*- C++ -*- // -// This file is part of the VSLSI Stand-Alone Software. +// This file is part of the VLSI Stand-Alone Software. // Copyright (c) UPMC 2013-2013, All Rights Reserved // // +-----------------------------------------------------------------+ diff --git a/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h b/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h new file mode 100644 index 00000000..938e0259 --- /dev/null +++ b/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h @@ -0,0 +1,85 @@ +// -*- C++ -*- +// +// This file is part of the VLSI Stand-Alone Software. +// Copyright (c) UPMC 2013-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | V L S I Stand - Alone Parsers / Drivers | +// | M i s c e l l a n e o u s U t i l i t i e s | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./Dots.h" | +// +-----------------------------------------------------------------+ + + +#ifndef VLSISAPD_UTILITIES_DOTS_H +#define VLSISAPD_UTILITIES_DOTS_H + +#include +#include + + +namespace Utilities { + + + class Dots { + public: + enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02 }; + public: + inline Dots ( std::ostream& + , const std::string& indent + , unsigned int width =70 + , unsigned int divider= 1 ); + inline void setWidth ( unsigned int ); + inline void setDivider ( unsigned int ); + inline void reset ( unsigned int flags ); + inline void CR (); + void dot (); + void finish ( unsigned int flags ); + private: + inline void _flush ( char ); + private: + std::ostream& _ostream; + std::string _indent; + unsigned int _width; + unsigned int _divider; + unsigned int _count; + unsigned int _flags; + }; + + + inline Dots::Dots ( std::ostream& o, const std::string& indent, unsigned int width, unsigned int divider ) + : _ostream(o) + , _indent (indent) + , _width (width) + , _divider(divider) + , _count (0) + , _flags (FirstDot) + { } + + inline void Dots::setWidth ( unsigned int w ) { _width=w; } + inline void Dots::setDivider ( unsigned int d ) { _divider=d; } + + inline void Dots::_flush ( char c ) + { + _ostream.put( c ); + _ostream.flush(); + } + + inline void Dots::CR () + { + _flush('\n'); + } + + inline void Dots::reset ( unsigned int flags ) + { + _flags = flags; + _count = 0; + } + + +} // Utilities namespace. + +#endif // VLSISAPD_UTILITIES_DOTS_H