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:
parent
4842f21a2e
commit
9501b88110
|
@ -14,8 +14,8 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef CRL_ISPD05_BOOKSHELF
|
||||
#define CRL_ISPD05_BOOKSHELF
|
||||
#ifndef CRL_ISPD05_BOOKSHELF_H
|
||||
#define CRL_ISPD05_BOOKSHELF_H
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
|
@ -15,11 +15,14 @@
|
|||
|
||||
|
||||
#include <memory>
|
||||
#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<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 );
|
||||
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<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 ();
|
||||
vector<Bookshelf::Net*>::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<string,Bookshelf::Node*>& nodes = circuit->getNodes();
|
||||
map<string,Bookshelf::Node*>::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<size_t,Bookshelf::Pin*>& pins = node->getPins();
|
||||
map<size_t,Bookshelf::Pin*>::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;
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iomanip>
|
||||
#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<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 )
|
||||
{
|
||||
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<Coloquinte::cell_area>().prod() << endl;
|
||||
|
||||
_circuit->cells[cellId].name = instanceName;
|
||||
_circuit->cells[cellId].sizes = cellSize;
|
||||
_circuit->cells[cellId].area = cellSize.cast<Coloquinte::cell_area>().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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<string,unsigned int> _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.
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
${KATABATIC_LIBRARIES}
|
||||
${KNIK_GRAPHICAL_LIBRARIES}
|
||||
${KNIK_LIBRARIES}
|
||||
${ETESIAN_GRAPHICAL_LIBRARIES}
|
||||
${ETESIAN_LIBRARIES}
|
||||
${MAUKA_GRAPHICAL_LIBRARIES}
|
||||
${MAUKA_LIBRARIES}
|
||||
${METIS_LIBRARIES}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 <cctype>
|
||||
#include <sstream>
|
||||
#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<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 )
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -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 << " <X Y>" << 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 << " <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" );
|
||||
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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <iostream>
|
||||
#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 };
|
||||
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
|
||||
|
|
|
@ -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 <string>
|
||||
#include <iostream>
|
||||
|
|
|
@ -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<char*>& );
|
||||
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; }
|
||||
|
||||
|
|
|
@ -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 <string>
|
||||
#include <iostream>
|
||||
|
@ -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
|
||||
|
|
|
@ -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 <string>
|
||||
#include <iostream>
|
||||
|
|
|
@ -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 )
|
||||
|
||||
|
|
|
@ -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.
|
|
@ -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
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue