First barebone implementation of Etesian. Support for ISPD05 benchmark.

Details:
* New: In <vlsispad/utilities>, new objet Dots for displaying a kind
    of progress bar.
* Change: In <vlsisapd/bookshelf>, 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 <hurricane>, 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 <crlcore>, Added translator for ISPD05 bookshelf, the
    circuit is *not* placed, unlike in ISPD04 and terminal nodes
    *are* true cells.
* New: In <unicorn>, added entry in import cell for ISPD05 benchmarks.
This commit is contained in:
Jean-Paul Chaput 2014-03-25 00:59:12 +01:00
parent 4842f21a2e
commit 9501b88110
22 changed files with 541 additions and 309 deletions

View File

@ -14,8 +14,8 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef CRL_ISPD05_BOOKSHELF #ifndef CRL_ISPD05_BOOKSHELF_H
#define CRL_ISPD05_BOOKSHELF #define CRL_ISPD05_BOOKSHELF_H
#include <string> #include <string>

View File

@ -15,11 +15,14 @@
#include <memory> #include <memory>
#include "vlsisapd/utilities/Dots.h"
#include "vlsisapd/bookshelf/Exception.h" #include "vlsisapd/bookshelf/Exception.h"
#include "vlsisapd/bookshelf/Node.h" #include "vlsisapd/bookshelf/Node.h"
#include "vlsisapd/bookshelf/Pin.h" #include "vlsisapd/bookshelf/Pin.h"
#include "vlsisapd/bookshelf/Net.h" #include "vlsisapd/bookshelf/Net.h"
#include "vlsisapd/bookshelf/Row.h"
#include "vlsisapd/bookshelf/Circuit.h" #include "vlsisapd/bookshelf/Circuit.h"
#include "vlsisapd/bookshelf/Parser.h"
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/DataBase.h" #include "hurricane/DataBase.h"
@ -31,6 +34,7 @@
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/Library.h" #include "hurricane/Library.h"
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "crlcore/ToolBox.h" #include "crlcore/ToolBox.h"
#include "crlcore/Ispd05Bookshelf.h" #include "crlcore/Ispd05Bookshelf.h"
@ -43,6 +47,9 @@ namespace {
using namespace CRL; using namespace CRL;
DbU::Unit pitch = 5.0;
void addSupplyNets ( Cell* cell ) void addSupplyNets ( Cell* cell )
{ {
Net* vss = Net::create ( cell, "vss" ); Net* vss = Net::create ( cell, "vss" );
@ -59,70 +66,45 @@ namespace {
Cell* toMasterCell ( AllianceFramework* af, Bookshelf::Node* node ) Cell* toMasterCell ( AllianceFramework* af, Bookshelf::Node* node )
{ {
if ( node->getHeight() > 16.0 ) return NULL;
Technology* technology = DataBase::getDB()->getTechnology(); Technology* technology = DataBase::getDB()->getTechnology();
Layer* METAL1 = technology->getLayer ( "METAL1" ); Layer* METAL1 = technology->getLayer ( "METAL1" );
Cell* master = af->createCell ( node->getName() ); Cell* master = af->createCell( node->getName() );
Box abutmentBox ( DbU::lambda( 0.0 ) Box abutmentBox( DbU::fromLambda( 0.0 )
, DbU::lambda( 0.0 ) , DbU::fromLambda( 0.0 )
, DbU::lambda( node->getWidth()*5.0 ) , DbU::fromLambda( node->getWidth ()*pitch )
, DbU::lambda( 50.0 ) , DbU::fromLambda( node->getHeight()*pitch )
); );
master->setAbutmentBox ( abutmentBox ); 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 , METAL1
, abutmentBox.getYMin()+DbU::lambda(3.0) , pinCenter.getX()
, DbU::lambda(6.0) , DbU::fromLambda(2.0)
, abutmentBox.getXMin() , pinCenter.getY() - DbU::fromLambda(0.5)
, abutmentBox.getXMax() , pinCenter.getY() + DbU::fromLambda(0.5)
); );
NetExternalComponents::setExternal ( segment ); 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<size_t,Bookshelf::Pin*>& pins = node->getPins();
map<size_t,Bookshelf::Pin*>::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 );
} }
return master; return master;
@ -140,76 +122,78 @@ namespace CRL {
using Hurricane::Library; using Hurricane::Library;
using Hurricane::Transformation; using Hurricane::Transformation;
using Hurricane::UpdateSession; using Hurricane::UpdateSession;
using Utilities::Dots;
Cell* Ispd05::load ( string benchmark ) Cell* Ispd05::load ( string benchmark )
{ {
AllianceFramework* af = AllianceFramework::get (); AllianceFramework* af = AllianceFramework::get();
UpdateSession::open (); UpdateSession::open ();
auto_ptr<Bookshelf::Circuit> circuit ( Bookshelf::Circuit::parse(benchmark) ); auto_ptr<Bookshelf::Circuit> 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<Bookshelf::Net*>& nets = circuit->getNets (); Dots dots ( cmess2, " ", 80, 1000 );
vector<Bookshelf::Net*>::iterator inet = nets.begin();
for ( ; inet != nets.end() ; ++inet ) { cmess1 << " - Converting Nets." << endl;
Net::create ( cell, (*inet)->getName() ); for ( auto net : circuit->getNets() ) {
dots.dot();
Net::create ( cell, net->getName() );
} }
dots.finish( Dots::Reset|Dots::FirstDot );
map<string,Bookshelf::Node*>& nodes = circuit->getNodes(); cmess1 << " - Converting Nodes." << endl;
map<string,Bookshelf::Node*>::iterator inode = nodes.begin(); for ( auto inode : circuit->getNodes() ) {
dots.dot();
Bookshelf::Node* node = inode.second;
Box abutmentBox; Cell* master = toMasterCell( af, node );
if (master == NULL) {
for ( ; inode != nodes.end() ; ++inode ) { cerr << Warning( "Skipping megacell <%s>.", node->getName().c_str() ) << endl;
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;
continue; continue;
} }
Instance* instance = Instance::create ( cell, node->getName(), master ); Instance* instance = Instance::create( cell, node->getName(), master );
map<size_t,Bookshelf::Pin*>& pins = node->getPins(); for ( auto ipin : node->getPins() ) {
map<size_t,Bookshelf::Pin*>::iterator ipin = pins.begin(); Name netName = ipin.second->getNet()->getName();
Net* masterNet = master->getNet( netName );
for ( size_t pinnb=0 ; ipin != pins.end() ; ++ipin, ++pinnb ) { instance->getPlug( masterNet )->setNet( cell->getNet(netName) );
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() );
} }
} }
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; return cell;
} }

View File

@ -17,8 +17,8 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <iomanip>
#include "coloquinte/circuit_graph.hxx" #include "coloquinte/circuit_graph.hxx"
#include "vlsisapd/utilities/Dots.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/Error.h" #include "hurricane/Error.h"
@ -35,6 +35,7 @@
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "hurricane/viewer/CellWidget.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
#include "crlcore/Measures.h" #include "crlcore/Measures.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
@ -146,6 +147,7 @@ namespace Etesian {
using std::pair; using std::pair;
using std::make_pair; using std::make_pair;
using std::unordered_map; using std::unordered_map;
using Utilities::Dots;
using Hurricane::DebugSession; using Hurricane::DebugSession;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::inltrace; using Hurricane::inltrace;
@ -163,11 +165,13 @@ namespace Etesian {
using Hurricane::RoutingPad; using Hurricane::RoutingPad;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Occurrence; using Hurricane::Occurrence;
using Hurricane::CellWidget;
using CRL::ToolEngine; using CRL::ToolEngine;
using CRL::AllianceFramework; using CRL::AllianceFramework;
using CRL::addMeasure; using CRL::addMeasure;
using CRL::Measures; using CRL::Measures;
using CRL::MeasuresSet; using CRL::MeasuresSet;
using CRL::CatalogExtension;
const char* missingEtesian = const char* missingEtesian =
@ -190,9 +194,12 @@ namespace Etesian {
EtesianEngine::EtesianEngine ( Cell* cell ) EtesianEngine::EtesianEngine ( Cell* cell )
: ToolEngine (cell) : ToolEngine (cell)
, _circuit (NULL) , _configuration(NULL)
, _cellsToIds() , _flags (0)
, _circuit (NULL)
, _cellsToIds ()
, _cellWidget (NULL)
{ } { }
@ -236,10 +243,62 @@ namespace Etesian {
{ return _configuration; } { 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<Occurrence> feedOccurrences;
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
{
dots.dot();
if ((_flags & FlatDesign) and not (*ioccurrence).getPath().getTailPath().isEmpty())
_flags &= ~FlatDesign;
Instance* instance = static_cast<Instance*>((*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<Instance*>(ioccurrence.getEntity());
instance->destroy();
}
UpdateSession::close();
dots.finish( Dots::Reset );
if (_cellWidget) _cellWidget->refresh();
_flags |= NoPlacement;
}
void EtesianEngine::place ( unsigned int slowMotion ) 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 ); getCell()->flattenNets( true );
// Coloquinte circuit description data-structures. // Coloquinte circuit description data-structures.
@ -247,6 +306,9 @@ namespace Etesian {
_circuit->cells .resize( getCell()->getLeafInstanceOccurrences().getSize() ); _circuit->cells .resize( getCell()->getLeafInstanceOccurrences().getSize() );
_circuit->hypernets.resize( getCell()->getNets().getSize() ); _circuit->hypernets.resize( getCell()->getNets().getSize() );
cmess1 << " - Converting Instances (Bookshelf nodes)" << endl;
cout.flush();
Coloquinte::cell_id cellId = 0; Coloquinte::cell_id cellId = 0;
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
{ {
@ -257,12 +319,16 @@ namespace Etesian {
instanceName.erase( 0, 1 ); instanceName.erase( 0, 1 );
instanceName.erase( instanceName.size()-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 () ) Coloquinte::circuit_coordinate cellSize ( masterCell->getAbutmentBox().getWidth () / DbU::fromLambda(5.0)
, DbU::toLambda( masterCell->getAbutmentBox().getHeight() )); , masterCell->getAbutmentBox().getHeight() / DbU::fromLambda(5.0) );
_cellsToIds.insert( make_pair(instanceName,cellId) ); _cellsToIds.insert( make_pair(instanceName,cellId) );
dots.dot();
//cerr << instanceName << " " << (int)instance->getPlacementStatus().getCode()
// << " area:" << cellSize.cast<Coloquinte::cell_area>().prod() << endl;
_circuit->cells[cellId].name = instanceName; _circuit->cells[cellId].name = instanceName;
_circuit->cells[cellId].sizes = cellSize; _circuit->cells[cellId].sizes = cellSize;
_circuit->cells[cellId].area = cellSize.cast<Coloquinte::cell_area>().prod(); _circuit->cells[cellId].area = cellSize.cast<Coloquinte::cell_area>().prod();
@ -271,6 +337,9 @@ namespace Etesian {
cellId++; cellId++;
} }
dots.finish( Dots::Reset|Dots::FirstDot );
cmess1 << " - Converting Nets (Bookshelf nets)" << endl;
unsigned int netId = 0; unsigned int netId = 0;
forEach ( Net*, inet, getCell()->getNets() ) forEach ( Net*, inet, getCell()->getNets() )
@ -286,14 +355,16 @@ namespace Etesian {
} }
if (af->isBLOCKAGE((*inet)->getName())) continue; if (af->isBLOCKAGE((*inet)->getName())) continue;
cerr << (*inet)->getName() << endl; dots.dot();
//cerr << (*inet)->getName() << endl;
forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) {
cerr << " " << (*irp)->getOccurrence().getCompactString() << endl; //cerr << " " << (*irp)->getOccurrence().getCompactString() << endl;
string insName = extractInstanceName( *irp ); string insName = extractInstanceName( *irp );
Point offset = extractRpOffset ( *irp ); Point offset = extractRpOffset ( *irp );
cerr << " Master Cell: " << (*irp)->getOccurrence().getMasterCell() << endl; //cerr << " Master Cell: " << (*irp)->getOccurrence().getMasterCell() << endl;
cerr << " Rebuilt instance name: " << insName << " " << offset << endl; //cerr << " Rebuilt instance name: " << insName << " " << offset << endl;
auto iid = _cellsToIds.find( insName ); auto iid = _cellsToIds.find( insName );
if (iid == _cellsToIds.end() ) { if (iid == _cellsToIds.end() ) {
@ -307,8 +378,8 @@ namespace Etesian {
Coloquinte::cell::pin cellPin; Coloquinte::cell::pin cellPin;
//cellPin.name = extractTerminalName( *irp ); //cellPin.name = extractTerminalName( *irp );
cellPin.d = extractDirection ( *irp ); cellPin.d = extractDirection ( *irp );
cellPin.offs.x() = DbU::toLambda( offset.getX() ); cellPin.offs.x() = offset.getX() / DbU::fromLambda(5.0);
cellPin.offs.y() = DbU::toLambda( offset.getY() ); cellPin.offs.y() = offset.getY() / DbU::fromLambda(5.0);
cellPin.ind = cellPinId; cellPin.ind = cellPinId;
_circuit->cells[cellId].pins.push_back( cellPin ); _circuit->cells[cellId].pins.push_back( cellPin );
} }
@ -316,6 +387,7 @@ namespace Etesian {
netId++; netId++;
} }
dots.finish( Dots::Reset );
_circuit->position_overlays.resize(1); _circuit->position_overlays.resize(1);
_circuit->position_overlays[0].x_pos = Coloquinte::circuit_vector( _cellsToIds.size() ); _circuit->position_overlays[0].x_pos = Coloquinte::circuit_vector( _cellsToIds.size() );
@ -329,36 +401,60 @@ namespace Etesian {
} }
_circuit->bounds = Coloquinte::circuit_box _circuit->bounds = Coloquinte::circuit_box
( Coloquinte::circuit_coordinate::Zero() ( Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMin() / DbU::fromLambda(5.0)
, Coloquinte::circuit_coordinate( { DbU::toLambda(getCell()->getAbutmentBox().getWidth ()) , getCell()->getAbutmentBox().getYMin() / DbU::fromLambda(5.0) } )
, DbU::toLambda(getCell()->getAbutmentBox().getHeight()) } )); , 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; cmess1 << " o Running Coloquinte." << endl;
for(int j = 0; j < 3; j++){ 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] _circuit->position_overlays[0]
= Coloquinte::solve_quadratic_model( *_circuit = Coloquinte::solve_quadratic_model( *_circuit
, _circuit->position_overlays[0] , _circuit->position_overlays[0]
, _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; float strength = 0.000001;
strength_incr = 0.000002; float strength_incr = 0.000002;
cmess1 << " - Optimizing placement..." << endl;
_circuit->position_overlays.resize(2); _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] _circuit->position_overlays[1]
= Coloquinte::legalize( *_circuit = Coloquinte::legalize( *_circuit
, 1.0 , 1.0
, _circuit->position_overlays[0] , _circuit->position_overlays[0]
, 1
, false , 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] _circuit->position_overlays[0]
= Coloquinte::solve_quadratic_model( *_circuit = Coloquinte::solve_quadratic_model( *_circuit
@ -366,15 +462,24 @@ namespace Etesian {
, _circuit->position_overlays[1] , _circuit->position_overlays[1]
, strength , strength
); );
cout << "At " << time(NULL) << " and iteration " << j timeDelta = time(NULL) - startTime;
<< ", lower bound is " << /*B2B_wirelength(*_circuit, _circuit->position_overlays[0]) <<*/ endl; 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(); UpdateSession::open();
@ -392,18 +497,21 @@ namespace Etesian {
if (iid == _cellsToIds.end() ) { if (iid == _cellsToIds.end() ) {
cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl; cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl;
} else { } else {
instancePosition.setX( DbU::fromLambda(_circuit->position_overlays[0].x_pos[(*iid).second]) ); instancePosition.setX( _circuit->position_overlays[placementId].x_pos[(*iid).second] * DbU::fromLambda(5.0) );
instancePosition.setY( DbU::fromLambda(_circuit->position_overlays[0].y_pos[(*iid).second]) ); 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 // This is temporary as it's not trans-hierarchic: we ignore the posutions
// of all the intermediary instances. // of all the intermediary instances.
instance->setTransformation( instancePosition ); instance->setTransformation( instancePosition );
instance->setPlacementStatus( Instance::PlacementStatus::PLACED );
} }
} }
UpdateSession::close(); UpdateSession::close();
if (_cellWidget) _cellWidget->refresh();
} }

View File

@ -65,6 +65,7 @@ namespace Etesian {
EtesianEngine* etesian = EtesianEngine::get( cell ); EtesianEngine* etesian = EtesianEngine::get( cell );
if (not etesian) { if (not etesian) {
etesian = EtesianEngine::create( cell ); etesian = EtesianEngine::create( cell );
etesian->setCellWidget( _viewer->getCellWidget() );
} else } else
cerr << Warning( "%s already has a Etesian engine.", getString(cell).c_str() ) << endl; cerr << Warning( "%s already has a Etesian engine.", getString(cell).c_str() ) << endl;
@ -99,6 +100,10 @@ namespace Etesian {
emit cellPreModificated(); emit cellPreModificated();
_viewer->clearToolInterrupt(); _viewer->clearToolInterrupt();
etesian->resetPlacement();
emit cellPostModificated();
emit cellPostModificated();
etesian->place(); etesian->place();
emit cellPostModificated(); emit cellPostModificated();
} }

View File

@ -30,6 +30,7 @@ namespace Hurricane {
class Layer; class Layer;
class Net; class Net;
class Cell; class Cell;
class CellWidget;
} }
#include "crlcore/ToolEngine.h" #include "crlcore/ToolEngine.h"
@ -49,7 +50,8 @@ namespace Etesian {
// Class : "Etesian::EtesianEngine". // Class : "Etesian::EtesianEngine".
class EtesianEngine : public CRL::ToolEngine { class EtesianEngine : public CRL::ToolEngine {
public:
enum Flag { NoPlacement=0x0001, FlatDesign=0x0002 };
public: public:
static const Name& staticGetName (); static const Name& staticGetName ();
static EtesianEngine* create ( Cell* ); static EtesianEngine* create ( Cell* );
@ -57,8 +59,10 @@ namespace Etesian {
public: public:
virtual Configuration* getConfiguration (); virtual Configuration* getConfiguration ();
virtual const Name& getName () const; virtual const Name& getName () const;
inline void setCellWidget ( Hurricane::CellWidget* );
void resetPlacement ();
void place ( unsigned int slowMotion=0 ); void place ( unsigned int slowMotion=0 );
void _updatePlacement (); void _updatePlacement ( unsigned int placementId );
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual std::string _getString () const; virtual std::string _getString () const;
virtual std::string _getTypeName () const; virtual std::string _getTypeName () const;
@ -68,8 +72,10 @@ namespace Etesian {
static Name _toolName; static Name _toolName;
protected: protected:
Configuration* _configuration; Configuration* _configuration;
unsigned int _flags;
Coloquinte::circuit* _circuit; Coloquinte::circuit* _circuit;
std::unordered_map<string,unsigned int> _cellsToIds; std::unordered_map<string,unsigned int> _cellsToIds;
Hurricane::CellWidget* _cellWidget;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.
@ -84,6 +90,7 @@ namespace Etesian {
// Inline Functions. // Inline Functions.
inline void EtesianEngine::setCellWidget ( Hurricane::CellWidget* cw ) { _cellWidget = cw; }
// Variables. // Variables.

View File

@ -216,7 +216,7 @@ void Cell::flattenNets(bool buildRings)
} }
forEach ( Occurrence, iplugOccurrence, hyperNet.getLeafPlugOccurrences() ) { 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 (); currentRP->materialize ();
if ( buildRings ) { if ( buildRings ) {
if ( previousRP ) { if ( previousRP ) {

View File

@ -47,6 +47,8 @@
${KATABATIC_LIBRARIES} ${KATABATIC_LIBRARIES}
${KNIK_GRAPHICAL_LIBRARIES} ${KNIK_GRAPHICAL_LIBRARIES}
${KNIK_LIBRARIES} ${KNIK_LIBRARIES}
${ETESIAN_GRAPHICAL_LIBRARIES}
${ETESIAN_LIBRARIES}
${MAUKA_GRAPHICAL_LIBRARIES} ${MAUKA_GRAPHICAL_LIBRARIES}
${MAUKA_LIBRARIES} ${MAUKA_LIBRARIES}
${METIS_LIBRARIES} ${METIS_LIBRARIES}

View File

@ -2,7 +2,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // 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 | // | C O R I O L I S |
@ -65,6 +65,9 @@ using namespace Metis;
#include "mauka/GraphicMaukaEngine.h" #include "mauka/GraphicMaukaEngine.h"
using namespace Mauka; using namespace Mauka;
#include "etesian/GraphicEtesianEngine.h"
using namespace Etesian;
#include "knik/GraphicKnikEngine.h" #include "knik/GraphicKnikEngine.h"
using namespace Knik; using namespace Knik;
@ -326,6 +329,7 @@ int main ( int argc, char *argv[] )
unicorn->setApplicationName ( QObject::tr("cgt") ); unicorn->setApplicationName ( QObject::tr("cgt") );
unicorn->registerTool ( Mauka::GraphicMaukaEngine::grab() ); unicorn->registerTool ( Mauka::GraphicMaukaEngine::grab() );
unicorn->registerTool ( Etesian::GraphicEtesianEngine::grab() );
//unicorn->registerTool ( Knik::GraphicKnikEngine::grab() ); //unicorn->registerTool ( Knik::GraphicKnikEngine::grab() );
unicorn->registerTool ( Kite::GraphicKiteEngine::grab() ); unicorn->registerTool ( Kite::GraphicKiteEngine::grab() );
//unicorn->setEnableRedrawInterrupt ( true ); //unicorn->setEnableRedrawInterrupt ( true );

View File

@ -198,7 +198,6 @@ namespace Unicorn {
break; break;
case ImportCellDialog::Ispd05: case ImportCellDialog::Ispd05:
cell = Ispd05::load ( cellName.toStdString() ); cell = Ispd05::load ( cellName.toStdString() );
cerr << "Cell " << " successfully loaded." << endl;
break; break;
case ImportCellDialog::Iccad04: case ImportCellDialog::Iccad04:
cell = Iccad04Lefdef::load ( cellName.toStdString() , 0 ); cell = Iccad04Lefdef::load ( cellName.toStdString() , 0 );
@ -214,7 +213,6 @@ namespace Unicorn {
viewer = UnicornGui::create (); viewer = UnicornGui::create ();
viewer->show (); viewer->show ();
} }
cerr << "Loading " << cell->getName() << " into the viewer." << endl;
viewer->setCell ( cell ); viewer->setCell ( cell );
} else } else
cerr << "[ERROR] Cell not found: " << cellName.toStdString() << endl; cerr << "[ERROR] Cell not found: " << cellName.toStdString() << endl;

View File

@ -2,7 +2,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // 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 | // | V L S I Stand - Alone Parsers / Drivers |

View File

@ -86,10 +86,10 @@ namespace Bookshelf {
{ _rows.push_back ( row ); } { _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; 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 ); Utilities::Path rootDirectory ( directory );
if ( not rootDirectory.exists() ) { if ( not rootDirectory.exists() ) {
rootDirectory.mkdir(); rootDirectory.mkdir();
} }
if ( flags & Nodes ) { if ( slots & Nodes ) {
Utilities::Path nodesPath ( rootDirectory ); Utilities::Path nodesPath ( rootDirectory );
if ( getNodesName().empty() ) if ( getNodesName().empty() )
nodesPath /= getDesignName() + ".nodes"; nodesPath /= getDesignName() + ".nodes";
@ -233,7 +233,7 @@ namespace Bookshelf {
ofnodes.close (); ofnodes.close ();
} }
if ( flags & Nets ) { if ( slots & Nets ) {
Utilities::Path netsPath ( rootDirectory ); Utilities::Path netsPath ( rootDirectory );
if ( getNetsName().empty() ) if ( getNetsName().empty() )
netsPath /= getDesignName() + ".nets"; netsPath /= getDesignName() + ".nets";
@ -245,7 +245,7 @@ namespace Bookshelf {
ofnets.close (); ofnets.close ();
} }
if ( (flags & Scl) and (hasScl()) ) { if ( (slots & Scl) and (hasScl()) ) {
Utilities::Path sclPath ( rootDirectory ); Utilities::Path sclPath ( rootDirectory );
if ( getSclName().empty() ) if ( getSclName().empty() )
sclPath /= getDesignName() + ".scl"; sclPath /= getDesignName() + ".scl";
@ -257,7 +257,7 @@ namespace Bookshelf {
ofscl.close (); ofscl.close ();
} }
if ( (flags & Pl) and (hasPl()) ) { if ( (slots & Pl) and (hasPl()) ) {
Utilities::Path plPath ( rootDirectory ); Utilities::Path plPath ( rootDirectory );
if ( getPlName().empty() ) if ( getPlName().empty() )
plPath /= getDesignName() + ".pl"; plPath /= getDesignName() + ".pl";

View File

@ -1,8 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // 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 | // | V L S I Stand - Alone Parsers / Drivers |
@ -15,6 +14,7 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include <cctype>
#include <sstream> #include <sstream>
#include "vlsisapd/bookshelf/Exception.h" #include "vlsisapd/bookshelf/Exception.h"
#include "vlsisapd/bookshelf/Node.h" #include "vlsisapd/bookshelf/Node.h"
@ -71,7 +71,7 @@ namespace Bookshelf {
, _stream () , _stream ()
, _buffer () , _buffer ()
, _tokens () , _tokens ()
, _flags (0) , _flags (StrictSyntax)
, _state (0) , _state (0)
, _net (NULL) , _net (NULL)
, _row (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<lowerA.size() ; ++i ) lowerA[i] = tolower( lowerA[i] );
for ( size_t i=0 ; i<lowerB.size() ; ++i ) lowerB[i] = tolower( lowerB[i] );
return lowerA.compare(lowerB);
}
void Parser::_parseFormatRevision ( const std::string& slotName ) void Parser::_parseFormatRevision ( const std::string& slotName )
{ {
std::string formatHeader = "UCLA " + slotName + " 1.0"; std::string formatHeader = "UCLA " + slotName + " 1.0";
if ( formatHeader.compare(_buffer) != 0 ) if ( _keywordCompare(formatHeader,_buffer) != 0 )
throw Exception("Bookshelf::Parse(): Invalid format revision for <.%s> slot.",slotName.c_str()); throw Exception("Bookshelf::Parse(): Invalid format revision for <.%s> slot.",slotName.c_str());
} }
@ -165,9 +179,9 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 3 ) if ( (_tokens.size() < 3 )
or ( token.compare(_tokens[0]) != 0) or (_keywordCompare(token,_tokens[0]) != 0)
or (std::string(":" ).compare(_tokens[1]) != 0) ) or (_keywordCompare(":" ,_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid %s in <.%s>.",_lineno, token.c_str(),slotName.c_str()); 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; //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 ) { for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) {
//std::cerr << "F:" << _tokens[itoken] << " "; //std::cerr << "F:" << _tokens[itoken] << " ";
if ( symmetryTokens ) { if ( symmetryTokens ) {
if ( std::string("X" ).compare(_tokens[itoken]) == 0 ) { symmetry |= Symmetry::X; continue; } if ( _keywordCompare("X" ,_tokens[itoken]) == 0 ) { symmetry |= Symmetry::X; continue; }
if ( std::string("Y" ).compare(_tokens[itoken]) == 0 ) { symmetry |= Symmetry::Y; continue; } if ( _keywordCompare("Y" ,_tokens[itoken]) == 0 ) { symmetry |= Symmetry::Y; continue; }
if ( std::string("R90").compare(_tokens[itoken]) == 0 ) { symmetry |= Symmetry::R90; continue; } if ( _keywordCompare("R90",_tokens[itoken]) == 0 ) { symmetry |= Symmetry::R90; continue; }
symmetryTokens = false; symmetryTokens = false;
} }
if ( std::string("terminal").compare(_tokens[itoken]) == 0 ) { terminal = true; continue; } if ( _keywordCompare("terminal",_tokens[itoken]) == 0 ) { terminal = true; continue; }
if ( std::string(":").compare(_tokens[itoken]) == 0 ) { symmetryTokens = true; continue; } if ( _keywordCompare(":" ,_tokens[itoken]) == 0 ) { symmetryTokens = true; continue; }
//std::cerr << " <X Y>" << std::endl; //std::cerr << " <X Y>" << std::endl;
@ -261,8 +275,8 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 3 ) if ( (_tokens.size() < 3 )
or (std::string("NetDegree").compare(_tokens[0]) != 0) or (_keywordCompare("NetDegree",_tokens[0]) != 0)
or (std::string(":" ).compare(_tokens[1]) != 0) ) or (_keywordCompare(":" ,_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid NetDegree in <.nets>.",_lineno); throw Exception("Bookshelf::Parse(): @%d, Invalid NetDegree in <.nets>.",_lineno);
std::string name; std::string name;
@ -286,16 +300,16 @@ namespace Bookshelf {
for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) { for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) {
//std::cerr << "F:" << _tokens[itoken] << " "; //std::cerr << "F:" << _tokens[itoken] << " ";
if ( tokenDirection ) { if ( tokenDirection ) {
if ( std::string("I").compare(_tokens[itoken]) == 0 ) { direction |= Direction::Input; } if ( _keywordCompare("I",_tokens[itoken]) == 0 ) { direction |= Direction::Input; }
if ( std::string("O").compare(_tokens[itoken]) == 0 ) { direction |= Direction::Output; } if ( _keywordCompare("O",_tokens[itoken]) == 0 ) { direction |= Direction::Output; }
if ( std::string("B").compare(_tokens[itoken]) == 0 ) { direction |= Direction::Bidirectional; } if ( _keywordCompare("B",_tokens[itoken]) == 0 ) { direction |= Direction::Bidirectional; }
if ( direction != Direction::Disabled ) { if ( direction != Direction::Disabled ) {
tokenDirection = false; tokenDirection = false;
continue; continue;
} }
} }
if ( std::string(":").compare(_tokens[itoken]) == 0 ) { if ( _keywordCompare(":",_tokens[itoken]) == 0 ) {
tokenDirection = false; tokenDirection = false;
if ( ++itoken == _tokens.size() ) if ( ++itoken == _tokens.size() )
@ -382,8 +396,8 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 2) if ( (_tokens.size() < 2)
or (std::string("CoreRow" ).compare(_tokens[0]) != 0) or (_keywordCompare("CoreRow" ,_tokens[0]) != 0)
or (std::string("Horizontal").compare(_tokens[1]) != 0) ) or (_keywordCompare("Horizontal",_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow line in <.scl>.",_lineno); throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow line in <.scl>.",_lineno);
_row = new Row (); _row = new Row ();
@ -396,20 +410,22 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 3) if ( (_tokens.size() < 3)
or (std::string("Siteorient").compare(_tokens[0]) != 0) or (_keywordCompare("Siteorient",_tokens[0]) != 0)
or (std::string(":" ).compare(_tokens[1]) != 0) ) or (_keywordCompare(":" ,_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid Row siteorient line in <.scl>.",_lineno); 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); } if ( _keywordCompare("N" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::N); }
else if ( std::string("E" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::E); } else if ( _keywordCompare("E" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::E); }
else if ( std::string("S" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::S); } else if ( _keywordCompare("S" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::S); }
else if ( std::string("W" ).compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::W); } else if ( _keywordCompare("W" ,_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::W); }
else if ( std::string("FN").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FN); } else if ( _keywordCompare("FN",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FN); }
else if ( std::string("FE").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FE); } else if ( _keywordCompare("FE",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FE); }
else if ( std::string("FS").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FS); } else if ( _keywordCompare("FS",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FS); }
else if ( std::string("FW").compare(_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FW); } else if ( _keywordCompare("FW",_tokens[2]) == 0 ) { _row->setSiteorient(Orientation::FW); }
else else {
throw Exception("Bookshelf::Parse(): @%d, Invalid Row siteorient line in <.scl>.",_lineno); //throw Exception("Bookshelf::Parse(): @%d, Invalid Row siteorient line in <.scl>.",_lineno);
_row->setSiteorient(Orientation::N);
}
} }
@ -418,15 +434,17 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 3) if ( (_tokens.size() < 3)
or (std::string("Sitesymmetry").compare(_tokens[0]) != 0) or (_keywordCompare("Sitesymmetry",_tokens[0]) != 0)
or (std::string(":" ).compare(_tokens[1]) != 0) ) or (_keywordCompare(":" ,_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno); throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno);
if ( std::string("X" ).compare(_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::X); } if ( _keywordCompare("X" ,_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::X); }
else if ( std::string("Y" ).compare(_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::Y); } else if ( _keywordCompare("Y" ,_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::Y); }
else if ( std::string("R90").compare(_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::R90); } else if ( _keywordCompare("R90",_tokens[2]) == 0 ) { _row->setSitesymmetry(Symmetry::R90); }
else else {
throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno); _row->setSitesymmetry(Symmetry::X);
//throw Exception("Bookshelf::Parse(): @%d, Invalid Row sitesymmetry line in <.scl>.",_lineno);
}
} }
@ -435,10 +453,10 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 6) if ( (_tokens.size() < 6)
or (std::string("SubrowOrigin").compare(_tokens[0]) != 0) or (_keywordCompare("SubrowOrigin",_tokens[0]) != 0)
or (std::string(":" ).compare(_tokens[1]) != 0) or (_keywordCompare(":" ,_tokens[1]) != 0)
or (std::string("Numsites" ).compare(_tokens[3]) != 0) or (_keywordCompare("Numsites" ,_tokens[3]) != 0)
or (std::string(":" ).compare(_tokens[4]) != 0) ) or (_keywordCompare(":" ,_tokens[4]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid Row SubrowOrigin line in <.scl>.",_lineno); throw Exception("Bookshelf::Parse(): @%d, Invalid Row SubrowOrigin line in <.scl>.",_lineno);
_row->setSubrowOrigin ( toDouble(_tokens[2]) ); _row->setSubrowOrigin ( toDouble(_tokens[2]) );
@ -451,7 +469,7 @@ namespace Bookshelf {
_tokenize (); _tokenize ();
if ( (_tokens.size() < 1) 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); throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow end line in <.scl>.",_lineno);
_row = NULL; _row = NULL;
@ -526,17 +544,17 @@ namespace Bookshelf {
for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) { for ( size_t itoken=1 ; itoken<_tokens.size() ; ++itoken ) {
//std::cerr << "F:" << _tokens[itoken] << " "; //std::cerr << "F:" << _tokens[itoken] << " ";
if ( orientationToken ) { if ( orientationToken ) {
if ( std::string("N" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::N; continue; } if ( _keywordCompare("N" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::N; continue; }
if ( std::string("E" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::E; continue; } if ( _keywordCompare("E" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::E; continue; }
if ( std::string("S" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::S; continue; } if ( _keywordCompare("S" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::S; continue; }
if ( std::string("W" ).compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::W; continue; } if ( _keywordCompare("W" ,_tokens[itoken]) == 0 ) { orientation |= Orientation::W; continue; }
if ( std::string("FN").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FN; continue; } if ( _keywordCompare("FN",_tokens[itoken]) == 0 ) { orientation |= Orientation::FN; continue; }
if ( std::string("FE").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FE; continue; } if ( _keywordCompare("FE",_tokens[itoken]) == 0 ) { orientation |= Orientation::FE; continue; }
if ( std::string("FS").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FS; continue; } if ( _keywordCompare("FS",_tokens[itoken]) == 0 ) { orientation |= Orientation::FS; continue; }
if ( std::string("FW").compare(_tokens[itoken]) == 0 ) { orientation |= Orientation::FW; continue; } if ( _keywordCompare("FW",_tokens[itoken]) == 0 ) { orientation |= Orientation::FW; continue; }
break; break;
} }
if ( std::string(":").compare(_tokens[itoken]) == 0 ) { orientationToken = true; continue; } if ( _keywordCompare(":",_tokens[itoken]) == 0 ) { orientationToken = true; continue; }
//std::cerr << " <X Y>" << std::endl; //std::cerr << " <X Y>" << 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" ); Utilities::Path auxPath ( designName+".aux" );
if ( not auxPath.exists() ) { if ( not auxPath.exists() ) {
throw Exception ( "%s .aux file not found.", auxPath.string().c_str() ); throw Exception ( "%s .aux file not found.", auxPath.string().c_str() );
@ -597,7 +617,7 @@ namespace Bookshelf {
_closeStream (); _closeStream ();
_tokenize (); _tokenize ();
if ( std::string(":").compare(_tokens[1]) == 0 ) { if ( _keywordCompare(":",_tokens[1]) == 0 ) {
// Re-ordering files: .nodes, .nets, .wts, .scl, .pl. // Re-ordering files: .nodes, .nets, .wts, .scl, .pl.
std::string ordereds [5]; std::string ordereds [5];
@ -608,23 +628,23 @@ namespace Bookshelf {
switch ( extension ) { switch ( extension ) {
case 0: 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]; ordereds[0] = _tokens[i];
break; break;
case 1: 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]; ordereds[1] = _tokens[i];
break; break;
case 2: 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]; ordereds[2] = _tokens[i];
break; break;
case 3: 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]; ordereds[3] = _tokens[i];
break; break;
case 4: 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]; ordereds[4] = _tokens[i];
break; break;
} }
@ -643,7 +663,7 @@ namespace Bookshelf {
Utilities::Path slotPath ( ordereds[iext] ); Utilities::Path slotPath ( ordereds[iext] );
if ( slotPath.exists() ) { if ( slotPath.exists() ) {
std::cout << " o Reading <" << slotPath.string() << ">" << std::endl; std::cout << " - Reading <" << slotPath.string() << ">" << std::endl;
switch ( iext ) { switch ( iext ) {
case 0: _parseNodes ( slotPath ); break; case 0: _parseNodes ( slotPath ); break;

View File

@ -1,15 +1,9 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // 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 | // | C O R I O L I S |
// | B o o k s h e l f P a r s e r | // | 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 | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Module : "./Pin.cpp" | // | C++ Module : "./Pin.cpp" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "vlsisapd/bookshelf/Node.h" #include "vlsisapd/bookshelf/Node.h"

View File

@ -1,15 +1,9 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // This file is part of the VLSI 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 | // | C O R I O L I S |
// | B o o k s h e l f P a r s e r | // | 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 | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./bookshelf/Circuit.h" | // | C++ Header : "./bookshelf/Circuit.h" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_CIRCUIT__ #ifndef VLSISAPD_BOOKSHELF_CIRCUIT_H
#define __VLSISAPD_BOOKSHELF_CIRCUIT__ #define VLSISAPD_BOOKSHELF_CIRCUIT_H
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -44,10 +35,11 @@ namespace Bookshelf {
enum Slot { Nets=0x1, Nodes=0x2, Wts=0x4, Scl=0x8, Pl=0x10, AllSlots=Nodes|Nets|Wts|Scl|Pl }; enum Slot { Nets=0x1, Nodes=0x2, Wts=0x4, Scl=0x8, Pl=0x10, AllSlots=Nodes|Nets|Wts|Scl|Pl };
public: public:
static Circuit* parse ( std::string design static Circuit* parse ( std::string design
, unsigned int flags =AllSlots , unsigned int slots =AllSlots
, unsigned int flags =0
); );
void drive ( std::string directory void drive ( std::string directory
, unsigned int flags =AllSlots , unsigned int slots =AllSlots
); );
public: public:
Circuit (); Circuit ();
@ -154,5 +146,4 @@ namespace Bookshelf {
} // End of Bookshelf namespace. } // End of Bookshelf namespace.
#endif // VLSISAPD_BOOKSHELF_CIRCUIT_H
#endif // __VLSISAPD_BOOKSHELF_CIRCUIT__

View File

@ -1,15 +1,9 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // 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 | // | C O R I O L I S |
// | B o o k s h e l f P a r s e r | // | 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 | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./bookshelf/Node.h" | // | C++ Header : "./bookshelf/Node.h" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_NODE__ #ifndef VLSISAPD_BOOKSHELF_NODE_H
#define __VLSISAPD_BOOKSHELF_NODE__ #define VLSISAPD_BOOKSHELF_NODE_H
#include <string> #include <string>
#include <iostream> #include <iostream>

View File

@ -1,8 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // This file is part of the VLSI 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 | // | V L S I Stand - Alone Parsers / Drivers |
@ -27,18 +26,28 @@
namespace Bookshelf { namespace Bookshelf {
class Row;
class Parser { class Parser {
public: public:
enum Flag { Comment=0x1, ExtraDatas=0x2 }; enum Flag { NoFlags = 0x0000
, Comment = 0x0001
, ExtraDatas = 0x0002
, StrictSyntax = 0x0004
};
public: public:
Parser (); 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: private:
bool _openStream ( const Utilities::Path& ); bool _openStream ( const Utilities::Path& );
void _closeStream (); void _closeStream ();
char* _readLine (); char* _readLine ();
void _tokenize (); void _tokenize ();
int _keywordCompare ( const std::string&, const std::string& ) const;
void _checkExtraDatas ( size_t maxtoken, std::vector<char*>& ); void _checkExtraDatas ( size_t maxtoken, std::vector<char*>& );
void _parseFormatRevision ( const std::string& slotName ); void _parseFormatRevision ( const std::string& slotName );
size_t _parseNum ( const std::string& slotName, const std::string& token ); 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::_isComment () const { return _flags&Comment; }
inline bool Parser::_hasExtraDatas () const { return _flags&ExtraDatas; } inline bool Parser::_hasExtraDatas () const { return _flags&ExtraDatas; }

View File

@ -1,30 +1,21 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // 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 | // | C O R I O L I S |
// | B o o k s h e l f P a r s e r | // | B o o k s h e l f P a r s e r |
// | | // | |
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./bookshelf/Pin.h" | // | C++ Header : "./vlsisapd/bookshelf/Pin.h" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_PIN__ #ifndef VLSISAPD_BOOKSHELF_PIN_H
#define __VLSISAPD_BOOKSHELF_PIN__ #define VLSISAPD_BOOKSHELF_PIN_H
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -78,7 +69,6 @@ namespace Bookshelf {
inline Node* Pin::getNode () const { return _node; } inline Node* Pin::getNode () const { return _node; }
} // End of Bookshelf namespace. } // Bookshelf namespace.
#endif // VLSISAPD_BOOKSHELF_PIN_H
#endif // __VLSISAPD_BOOKSHELF_PIN__

View File

@ -1,15 +1,9 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the VSLSI Stand-Alone Software. // This file is part of the VLSI 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 | // | C O R I O L I S |
// | B o o k s h e l f P a r s e r | // | 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 | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./bookshelf/Row.h" | // | C++ Header : "./bookshelf/Row.h" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_ROW__ #ifndef VLSISAPD_BOOKSHELF_ROW_H
#define __VLSISAPD_BOOKSHELF_ROW__ #define VLSISAPD_BOOKSHELF_ROW_H
#include <string> #include <string>
#include <iostream> #include <iostream>

View File

@ -3,11 +3,13 @@
include_directories ( ${VLSISAPD_SOURCE_DIR}/src/utilities/src include_directories ( ${VLSISAPD_SOURCE_DIR}/src/utilities/src
) )
set ( includes vlsisapd/utilities/Path.h set ( includes vlsisapd/utilities/Path.h
) vlsisapd/utilities/Dots.h
set ( cpps Path.cpp )
) set ( cpps Path.cpp
Dots.cpp
)
add_library ( vlsisapdutils ${cpps} ) add_library ( vlsisapdutils ${cpps} )
set_target_properties ( vlsisapdutils PROPERTIES VERSION 1.0 SOVERSION 1 ) set_target_properties ( vlsisapdutils PROPERTIES VERSION 1.0 SOVERSION 1 )

View File

@ -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.

View File

@ -1,7 +1,6 @@
// -*- C++ -*- // -*- 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 // Copyright (c) UPMC 2013-2013, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+

View File

@ -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 <string>
#include <iostream>
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