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
#define CRL_ISPD05_BOOKSHELF
#ifndef CRL_ISPD05_BOOKSHELF_H
#define CRL_ISPD05_BOOKSHELF_H
#include <string>

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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();
}

View File

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

View File

@ -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 ) {

View File

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

View File

@ -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 );

View File

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

View File

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

View File

@ -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";

View File

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

View File

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

View File

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

View File

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

View File

@ -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; }

View File

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

View File

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

View File

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

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++ -*-
//
// 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
//
// +-----------------------------------------------------------------+

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