* ./vlsisapd/src/bookshelf:

- New: A Bookshelf autonomic parser/driver. Made to parse and manipulate
        the ISPD04 benchmarks (ibm 01-18 series). Currently parses/drives
        .nodes, .nets, .scl, .pl, the .wts is not implemented yet.
This commit is contained in:
Jean-Paul Chaput 2010-08-18 20:35:50 +00:00
parent d3cc60a4ab
commit dd405e619f
21 changed files with 2432 additions and 0 deletions

View File

@ -53,6 +53,11 @@ IF(VLSISAPD_DIR_SEARCH)
FIND_LIBRARY(DTR_LIBRARY NAMES dtr PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX})
SET_FOUND (DTR)
# Bookshelf
FIND_PATH (BOOKSHELF_INCLUDE_DIR NAMES vlsisapd/bookshelf/Circuit.h PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES include)
FIND_LIBRARY(BOOKSHELF_LIBRARY NAMES bookshelf PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX})
SET_FOUND (BOOKSHELF)
# Configuration
FIND_PATH (CONFIGURATION_INCLUDE_DIR NAMES vlsisapd/configuration/ConfigurationWidget.h PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES include)
FIND_LIBRARY(CONFIGURATION_LIBRARY NAMES configuration PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX})

View File

@ -6,4 +6,5 @@ ENDIF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/openChams)
IF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr)
ADD_SUBDIRECTORY(dtr)
ENDIF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr)
ADD_SUBDIRECTORY(bookshelf)
ADD_SUBDIRECTORY(configuration)

View File

@ -0,0 +1 @@
ADD_SUBDIRECTORY(src)

View File

@ -0,0 +1,52 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Bookshelf.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
namespace bfs = boost::filesystem;
#include "vlsisapd/bookshelf/Bookshelf.h"
#include "vlsisapd/bookshelf/BookshelfException.h"
namespace Bookshelf {
BookshelfParser::BookshelfParser ()
{ }
void BookshelfParser::readFromFile ( std::string auxFile )
{
bfs::path auxPath ( auxFile );
if ( not bfs::exists(auxPath) ) {
throw BookshelfException ( "%s .aux file not found.", auxPath.string().c_str() );
}
std::cout << " o Reading Bookshelf .aux: <" << auxPath.string() << ">." << std::endl;
}
} // End of Bookself namespace.

View File

@ -0,0 +1,173 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Main.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <cmath>
#include <iostream>
#include <memory>
using namespace std;
#include <boost/program_options.hpp>
namespace boptions = boost::program_options;
#include <boost/filesystem/operations.hpp>
namespace bfs = boost::filesystem;
#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"
using namespace Bookshelf;
void doDumpDualNetlist ( Circuit* circuit )
{
map<string,Node*>& nodes = circuit->getNodes();
map<string,Node*>::iterator inode = nodes.begin();
for ( ; inode != nodes.end() ; ++inode ) {
cout << "NODE:" << (*inode).second->getName() << endl;
map<size_t,Pin*>& pins = (*inode).second->getPins();
map<size_t,Pin*>::iterator ipin = pins.begin();
for ( ; ipin != pins.end() ; ++ipin ) {
cout << " pin:" << (*ipin).second->getNet()->getName() << endl;
}
}
}
void doFindMegaCells ( Circuit* circuit )
{
size_t megacellsNb = 0;
map<string,Node*>& nodes = circuit->getNodes();
map<string,Node*>::iterator inode = nodes.begin();
for ( ; inode != nodes.end() ; ++inode ) {
Node* node = (*inode).second;
map<size_t,Pin*>& pins = node->getPins();
map<size_t,Pin*>::iterator ipin = pins.begin();
if ( (double)pins.size() > node->getWidth() ) {
cout << setw(4) << right << megacellsNb
<< ":megacell:" << node->getName()
<< " with " << pins.size() << " terminals"
<< " for " << setprecision(4) << node->getWidth() << " pitchs."
<< endl;
//for ( ; ipin != pins.end() ; ++ipin ) {
// cout << " pin:" << (*ipin).second->getNet()->getName() << endl;
//}
++megacellsNb;
}
}
}
void doIspd04Square ( Circuit* circuit )
{
vector<Row*>& rows = circuit->getRows ();
size_t deltaRows = (size_t)(round ( sqrt(2.0) * (double)rows.size() )) - rows.size();
double numsites = round ( rows[0]->getNumsites() / sqrt(2.0) );
for ( size_t irow=0 ; irow<rows.size() ; ++irow ) {
rows[irow]->setNumsites ( numsites );
}
double deltaRowCoordinate = rows[rows.size()-1]->getCoordinate();
for ( size_t irow=0 ; irow<deltaRows ; ++irow ) {
deltaRowCoordinate += 16.0;
Row* row = new Row();
row->setCoordinate ( deltaRowCoordinate );
row->setHeight ( 16.0 );
row->setSitewidth ( 1.0 );
row->setSitespacing ( 1.0 );
row->setSiteorient ( Orientation::N );
row->setSitesymmetry ( Symmetry::Y );
row->setSubrowOrigin ( 0.0 );
row->setNumsites ( numsites );
circuit->addRow ( row );
}
circuit->setNumRows ( circuit->getRows().size() );
circuit->setSclName ( circuit->getDesignName()+"square.scl" );
circuit->drive ( ".", Circuit::Scl );
}
int main ( int argc, char* argv[] )
{
int returnCode = 0;
try {
bool ispd04square;
bool findMegaCells;
bool dumpDualNetlist;
boptions::options_description options ("Command line arguments & options");
options.add_options()
( "help,h" , "Print this help." )
( "aux,a" , boptions::value<string>()
, "The path of the Bookshelf <.aux> file." )
( "dual-netlist" , boptions::bool_switch(&dumpDualNetlist)->default_value(false)
, "Print dual netlist representation (pins on each nodes)." )
( "find-megacells", boptions::bool_switch(&findMegaCells)->default_value(false)
, "Guess Mega-Cells by their pins number." )
( "ispd04-square" , boptions::bool_switch(&ispd04square)->default_value(false)
, "Change form factor of ISPD04 benchmarks to square." );
boptions::variables_map arguments;
boptions::store ( boptions::parse_command_line(argc,argv,options), arguments );
boptions::notify ( arguments );
if ( arguments.count("help") ) {
cout << options << endl;
exit ( 0 );
}
bfs::path::default_name_check ( bfs::portable_posix_name );
if ( arguments.count("aux") ) {
auto_ptr<Circuit> circuit ( Circuit::parse(arguments["aux"].as<string>()) );
circuit->check ();
if ( ispd04square ) doIspd04Square ( circuit.get() );
if ( findMegaCells ) doFindMegaCells ( circuit.get() );
if ( dumpDualNetlist ) doDumpDualNetlist ( circuit.get() );
}
}
catch ( Exception& e ) {
cerr << e.what() << endl;
returnCode = 128;
}
catch ( exception& e ) {
cerr << "[ERROR] Catched exception:\n " << e.what() << endl;
returnCode = 127;
}
return returnCode;
}

View File

@ -0,0 +1,32 @@
include_directories ( ${VLSISAPD_SOURCE_DIR}/src/bookshelf/src
${Boost_INCLUDE_DIRS}
)
set ( includes vlsisapd/bookshelf/Parser.h
vlsisapd/bookshelf/Node.h
vlsisapd/bookshelf/Pin.h
vlsisapd/bookshelf/Net.h
vlsisapd/bookshelf/Row.h
vlsisapd/bookshelf/Circuit.h
vlsisapd/bookshelf/Exception.h
)
set ( cpps Parser.cpp
Node.cpp
Pin.cpp
Net.cpp
Row.cpp
Circuit.cpp
Exception.cpp
)
set ( testcpps BookshelfTkMain.cpp )
add_library ( bookshelf ${cpps} )
#target_link_libraries ( bookshelf )
add_executable ( bookshelf-tk ${testcpps} )
target_link_libraries ( bookshelf-tk bookshelf ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} )
install ( TARGETS bookshelf DESTINATION lib${LIB_SUFFIX} )
install ( TARGETS bookshelf-tk DESTINATION bin )
install ( FILES ${includes} DESTINATION include/vlsisapd/bookshelf )

View File

@ -0,0 +1,280 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Circuit.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <sstream>
#include "vlsisapd/bookshelf/Exception.h"
#include "vlsisapd/bookshelf/Node.h"
#include "vlsisapd/bookshelf/Net.h"
#include "vlsisapd/bookshelf/Row.h"
#include "vlsisapd/bookshelf/Circuit.h"
#include "vlsisapd/bookshelf/Parser.h"
namespace Bookshelf {
Circuit::Circuit ()
: _designName ()
, _nodesName ()
, _netsName ()
, _wtsName ()
, _sclName ()
, _plName ()
, _flags (0)
, _numNodes (0)
, _numTerminals(0)
, _numPins (0)
, _maxPinId (0)
, _numRows (0)
, _nodes ()
, _nets ()
, _rows ()
{ }
Circuit::~Circuit ()
{
std::map<std::string,Node*>::iterator inode = _nodes.begin();
for ( ; inode != _nodes.end() ; ++inode )
delete (*inode).second;
}
Node* Circuit::getNode ( const std::string& name ) const
{
std::map<std::string,Node*>::const_iterator inode = _nodes.find(name);
if ( inode != _nodes.end() ) return (*inode).second;
return NULL;
}
Net* Circuit::getNet ( const std::string& name ) const
{
std::map<std::string,Net*>::const_iterator inet = _netsByName.find(name);
if ( inet != _netsByName.end() ) return (*inet).second;
return NULL;
}
void Circuit::addNode ( Node* node )
{ _nodes.insert ( make_pair(node->getName(),node) ); }
void Circuit::addNet ( Net* net )
{ _nets.push_back ( net ); }
void Circuit::addRow ( Row* row )
{ _rows.push_back ( row ); }
Circuit* Circuit::parse ( std::string auxFile, unsigned int flags )
{
Parser parser;
return parser.parse ( auxFile, flags );
}
bool Circuit::check () const
{
bool success = true;
if ( (size_t)_numNodes != _nodes.size() ) {
std::cerr << "[ERROR] Nodes number discrepency, "
<< _numNodes << " announceds but "
<< _nodes.size() << " founds." << std::endl;
success = false;
}
if ( (size_t)_numPins != _maxPinId ) {
std::cerr << "[ERROR] Pins number discrepency, "
<< _numPins << " announceds but "
<< _maxPinId << " founds." << std::endl;
success = false;
}
return false;
}
void Circuit::writeNodesToStream ( std::ostream& o )
{
o << "UCLA nodes 1.0" << std::endl;
o << std::endl;
o << "NumNodes : " << std::setw(20) << std::right << _numNodes << std::endl;
o << "NumTerminals : " << std::setw(16) << std::right << _numTerminals << std::endl;
std::map<std::string,Node*>::iterator inode = _nodes.begin();
for ( ; inode != _nodes.end() ; ++inode )
(*inode).second->writeToStream ( o, Nodes );
}
void Circuit::writeNetsToStream ( std::ostream& o )
{
o << "UCLA nets 1.0" << std::endl;
o << std::endl;
o << "NumNets : " << std::setw(10) << std::right << _nets.size() << std::endl;
o << "NumPins : " << std::setw(10) << std::right << _numPins << std::endl;
std::vector<Net*>::iterator inet = _nets.begin();
for ( ; inet != _nets.end() ; ++inet )
(*inet)->writeToStream ( o );
}
void Circuit::writeSclToStream ( std::ostream& o )
{
o << "UCLA scl 1.0" << std::endl;
o << std::endl;
o << "NumRows : " << std::setw(20) << std::right << _numRows << std::endl;
std::vector<Row*>::iterator irow = _rows.begin();
for ( ; irow != _rows.end() ; ++irow )
(*irow)->writeToStream ( o );
}
void Circuit::writePlToStream ( std::ostream& o )
{
o << "UCLA pl 1.0" << std::endl;
o << std::endl;
std::map<std::string,Node*>::iterator inode = _nodes.begin();
for ( ; inode != _nodes.end() ; ++inode )
(*inode).second->writeToStream ( o, Pl );
}
std::string Circuit::getAutomaticName ( size_t id )
{
std::ostringstream autoName;
autoName << "NET";
if ( id == 0 ) autoName << _nets.size();
else autoName << id;
return autoName.str();
}
bool Circuit::hasAutomaticName ( Net* net )
{
std::string autoName = getAutomaticName ( net->getId() );
return net->getName().compare(0,autoName.size(),autoName);
}
void Circuit::resolveNames ()
{
for ( size_t i=0 ; i<_nets.size() ; ++i ) {
if ( _nets[i]->getName().empty() ) continue;
_netsByName.insert ( make_pair(_nets[i]->getName(),_nets[i]) );
}
for ( size_t i=0 ; i<_nets.size() ; ++i ) {
if ( not _nets[i]->getName().empty() ) continue;
std::ostringstream format;
format << "NET" << (_nets[i]->getId()+1);
bool start = true;
std::string autoName = format.str();
while ( _netsByName.find(autoName) != _netsByName.end() ) {
if ( start or (*autoName.rbegin() == 'z') ) {
start = false;
autoName += 'a';
} else {
(*autoName.rbegin())++;
}
}
_nets[i]->setName ( autoName );
_netsByName.insert ( make_pair(autoName,_nets[i]) );
}
}
void Circuit::drive ( std::string directory, unsigned int flags )
{
bfs::path rootDirectory ( directory );
if ( not bfs::exists(rootDirectory) ) {
bfs::create_directory ( rootDirectory );
}
if ( flags & Nodes ) {
bfs::path nodesPath ( rootDirectory );
if ( getNodesName().empty() )
nodesPath /= getDesignName() + ".nodes";
else
nodesPath /= getNodesName();
bfs::ofstream ofnodes ( nodesPath );
writeNodesToStream ( ofnodes );
ofnodes.close ();
}
if ( flags & Nets ) {
bfs::path netsPath ( rootDirectory );
if ( getNetsName().empty() )
netsPath /= getDesignName() + ".nets";
else
netsPath /= getNetsName();
bfs::ofstream ofnets ( netsPath );
writeNetsToStream ( ofnets );
ofnets.close ();
}
if ( (flags & Scl) and (hasScl()) ) {
bfs::path sclPath ( rootDirectory );
if ( getSclName().empty() )
sclPath /= getDesignName() + ".scl";
else
sclPath /= getSclName();
bfs::ofstream ofscl ( sclPath );
writeSclToStream ( ofscl );
ofscl.close ();
}
if ( (flags & Pl) and (hasPl()) ) {
bfs::path plPath ( rootDirectory );
if ( getPlName().empty() )
plPath /= getDesignName() + ".pl";
else
plPath /= getPlName();
bfs::ofstream ofpl ( plPath );
writePlToStream ( ofpl );
ofpl.close ();
}
}
} // End of Bookshelf namespace.

View File

@ -0,0 +1,73 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Exception.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <cstdarg>
#include "vlsisapd/bookshelf/Exception.h"
namespace Bookshelf {
Exception::Exception ( const std::string& message ) throw()
: std::exception()
, _message(_addHeader(message.c_str()))
{ }
Exception::Exception ( const char* format, ... ) throw()
: std::exception()
, _message()
{
static char formatted [ 8192 ];
va_list args;
va_start ( args, format );
vsnprintf ( formatted, 8191, format, args );
va_end ( args );
_message = _addHeader(formatted);
}
Exception::Exception ( const Exception& e ) throw()
: std::exception()
, _message(e._message)
{ }
Exception::~Exception () throw()
{ }
const char* Exception::what () const throw()
{ return _message.c_str(); }
std::string Exception::_addHeader ( const char* rawMessage )
{ return std::string("[ERROR] ") + rawMessage; }
} // End of Bookshelf namespace.

View File

@ -0,0 +1,117 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Main.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <iostream>
#include <memory>
using namespace std;
#include <boost/program_options.hpp>
namespace boptions = boost::program_options;
#include <boost/filesystem/operations.hpp>
namespace bfs = boost::filesystem;
#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"
using namespace Bookshelf;
int main ( int argc, char* argv[] )
{
int returnCode = 0;
try {
boptions::options_description options ("Command line arguments & options");
options.add_options()
( "help,h", "Print this help." )
( "aux,a" , boptions::value<string>()
, "The path of the Bookshelf <.aux> file." );
boptions::variables_map arguments;
boptions::store ( boptions::parse_command_line(argc,argv,options), arguments );
boptions::notify ( arguments );
if ( arguments.count("help") ) {
cout << options << endl;
exit ( 0 );
}
bfs::path::default_name_check ( bfs::portable_posix_name );
if ( arguments.count("aux") ) {
auto_ptr<Circuit> circuit ( Circuit::parse(arguments["aux"].as<string>()) );
circuit->check ();
vector<Row*>& rows = circuit->getRows ();
for ( size_t irow=0 ; irow<rows.size() ; ++irow ) {
rows[irow]->setNumsites ( 1096.0 );
}
size_t rowAddition = 40;
for ( size_t irow=0 ; irow<rowAddition ; ++irow ) {
Row* row = new Row();
row->setCoordinate ( 1520.0 + (irow+1)*16.0 );
row->setHeight ( 16.0 );
row->setSitewidth ( 1.0 );
row->setSitespacing ( 1.0 );
row->setSiteorient ( Orientation::N );
row->setSitesymmetry ( Symmetry::Y );
row->setSubrowOrigin ( 0.0 );
row->setNumsites ( 1096.0 );
circuit->addRow ( row );
}
circuit->setNumRows ( circuit->getRows().size() );
circuit->setSclName ( arguments["aux"].as<string>()+"square.scl" );
circuit->drive ( ".", Circuit::Scl );
// map<string,Node*>& nodes = circuit->getNodes();
// map<string,Node*>::iterator inode = nodes.begin();
// for ( ; inode != nodes.end() ; ++inode ) {
// cerr << "NODE:" << (*inode).second->getName() << endl;
// map<size_t,Pin*>& pins = (*inode).second->getPins();
// map<size_t,Pin*>::iterator ipin = pins.begin();
// for ( ; ipin != pins.end() ; ++ipin ) {
// cerr << " pin:" << (*ipin).second->getNet()->getName() << endl;
// }
// }
}
}
catch ( Exception& e ) {
cerr << e.what() << endl;
returnCode = 128;
}
catch ( exception& e ) {
cerr << "[ERROR] Catched exception:\n " << e.what() << endl;
returnCode = 127;
}
return returnCode;
}

View File

@ -0,0 +1,75 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Net.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "vlsisapd/bookshelf/Pin.h"
#include "vlsisapd/bookshelf/Net.h"
#include "vlsisapd/bookshelf/Circuit.h"
namespace Bookshelf {
Net::Net ( Circuit* circuit, size_t degree, const std::string& name )
: _circuit(circuit)
, _id (circuit->getNets().size())
, _degree (degree)
, _name (name)
, _pins ()
{
//if ( _name.empty() )
// _name = circuit->getAutomaticName ();
circuit->addNet ( this );
}
Net::~Net ()
{
std::vector<Pin*>::iterator ipin = _pins.begin();
for ( ; ipin != _pins.end() ; ++ipin )
delete (*ipin);
}
void Net::addPin ( Pin* pin )
{
_pins.push_back(pin);
}
void Net::writeToStream ( std::ostream& o )
{
o << "NetDegree : " << _degree;
//if ( not _circuit->hasAutomaticName(this) )
o << " " << _name;
o << std::endl;
std::vector<Pin*>::iterator ipin = _pins.begin();
for ( ; ipin != _pins.end() ; ++ipin )
(*ipin)->writeToStream ( o );
}
} // End of Bookshelf namespace.

View File

@ -0,0 +1,111 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Node.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "vlsisapd/bookshelf/Exception.h"
#include "vlsisapd/bookshelf/Pin.h"
#include "vlsisapd/bookshelf/Node.h"
#include "vlsisapd/bookshelf/Circuit.h"
namespace Bookshelf {
Pin* Node::getPin ( size_t id ) const
{
std::map<size_t,Pin*>::const_iterator ipin = _pins.find(id);
if ( ipin != _pins.end() ) return (*ipin).second;
return NULL;
}
void Node::addPin ( Pin* pin )
{
if ( getPin(pin->getId()) != NULL ) {
throw Exception("Bookshelf::Node::addPin(): Node <%s> already connected to net id:%d"
,_name.c_str(),pin->getId());
}
_pins.insert ( std::make_pair(pin->getId(),pin) );
}
void Node::writeToStream ( std::ostream& o, unsigned int flags )
{
//std::cerr << "Node::writeToStream() " << (void*)this << std::endl;
if ( flags & Circuit::Nodes ) {
o << std::setw(20) << std::right << _name;
if ( (_width != 0.0) or (_height != 0.0) ) {
o << " " << std::setw(10) << std::right << _width << " " << std::setw(10) << std::right << _height;
}
if ( _terminal ) o << " terminal";
if ( _symmetry != Symmetry::Disabled ) {
o << " :";
if ( _symmetry & Symmetry::R90 ) o << " R90";
if ( _symmetry & Symmetry::X ) o << " X";
if ( _symmetry & Symmetry::Y ) o << " Y";
}
o << std::endl;
} else if ( flags & Circuit::Pl ) {
o << std::setw(20) << std::right << _name;
o << " " << std::setw(10) << std::right << _x << " " << std::setw(10) << std::right << _y;
if ( _orientation != Orientation::Disabled ) {
o << " :";
if ( _orientation == Orientation::N ) o << " N";
if ( _orientation == Orientation::E ) o << " E";
if ( _orientation == Orientation::S ) o << " S";
if ( _orientation == Orientation::W ) o << " W";
if ( _orientation == Orientation::FN ) o << " FN";
if ( _orientation == Orientation::FE ) o << " FE";
if ( _orientation == Orientation::FS ) o << " FS";
if ( _orientation == Orientation::FW ) o << " FW";
}
o << std::endl;
}
}
std::ostream& operator<< ( std::ostream& o, const Node* node )
{
o << "<Node " << node->_name;
if ( (node->_x != 0.0) or (node->_y != 0) ) {
o << " " << node->_x << " " << node->_y;
}
if ( node->_symmetry != Symmetry::Disabled ) {
o << " :";
if ( node->_symmetry & Symmetry::X ) o << " X";
if ( node->_symmetry & Symmetry::Y ) o << " Y";
if ( node->_symmetry & Symmetry::R90 ) o << " R90";
}
if ( node->_terminal ) {
o << " terminal";
}
return o;
}
} // End of Bookshelf namespace.

View File

@ -0,0 +1,676 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Parser.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <sstream>
#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"
namespace {
using namespace std;
inline long toLong ( const char* s )
{ long value; istringstream input(s); input >> value; return value; }
inline size_t toSizet ( const char* s )
{ size_t value; istringstream input(s); input >> value; return value; }
inline double toDouble ( const char* s )
{ double value; istringstream input(s); input >> value; return value; }
} // End of anonymous namespace.
namespace Bookshelf {
enum NodesParserState { NodesFormatRevision=1, NodesNumNodes, NodesNumTerminals, NodesNode };
enum NetsParserState { NetsFormatRevision=1, NetsNumNets, NetsNumPins, NetsDegree, NetsPin };
enum PlParserState { PlFormatRevision=1, PlNodePlace };
enum SclParserState { SclFormatRevision=1
, SclNumRows
, SclCoreRow
, SclCoordinate
, SclHeight
, SclSitewidth
, SclSitespacing
, SclSiteorient
, SclSitesymmetry
, SclSubrowOrigin
, SclCorerowEnd
, SclFinish
};
Parser::Parser ()
: _lineno (0)
, _stream ()
, _buffer ()
, _tokens ()
, _flags (0)
, _state (0)
, _net (NULL)
, _row (NULL)
, _circuit(NULL)
{ }
bool Parser::_openStream ( const bfs::path& filePath )
{
if ( _stream.is_open() ) _closeStream();
_stream.open ( filePath );
_lineno = 0;
return _stream.is_open();
}
void Parser::_closeStream ()
{
if ( _stream.is_open() ) _stream.close();
}
char* Parser::_readLine ()
{
bool textBeforeComment = false;
_flags &= ~Comment;
if ( _stream.is_open() ) {
_stream.getline ( _buffer, BufferSize );
++_lineno;
for ( size_t i=0 ; (_buffer[i] != '\0') and (i<BufferSize) ; ++i ) {
if ( _buffer[i] == '#' ) {
_flags |= Comment;
break;
} else if ( (_buffer[i] == ' ') or (_buffer[i] == '\t') )
continue;
textBeforeComment = true;
}
} else
_buffer[0] = '\0';
if ( (_flags & Comment) and (textBeforeComment) )
std::cerr << Exception("Text before comment at line %d.",_lineno).what() << std::endl;
if ( not textBeforeComment ) _flags |= Comment;
return _buffer;
}
void Parser::_tokenize ()
{
static std::string separators = " \t";
bool mergeSeparator = true;
char* ibuffer = _buffer;
_tokens.clear();
while ( *ibuffer != '\0' ) {
if ( separators.find(*ibuffer) != std::string::npos ) {
*ibuffer = '\0';
mergeSeparator = true;
} else {
if ( mergeSeparator ) {
//std::cerr << _tokens.size() << ":" << ibuffer << std::endl;
_tokens.push_back ( ibuffer );
}
mergeSeparator = false;
}
++ibuffer;
}
}
void Parser::_parseFormatRevision ( const std::string& slotName )
{
std::string formatHeader = "UCLA " + slotName + " 1.0";
if ( formatHeader.compare(_buffer) != 0 )
throw Exception("Bookshelf::Parse(): Invalid format revision for <.%s> slot.",slotName.c_str());
}
size_t Parser::_parseNum ( const std::string& slotName, const std::string& token )
{
_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());
//std::cerr << _tokens.size() << ":" << _tokens[2] << ":" << _circuit->getNumNodes() << std::endl;
return toSizet(_tokens[2]);
}
void Parser::_parseNodesNode ()
{
//std::cerr << "_buffer: " << _buffer << endl;
bool terminal = false;
unsigned int symmetry = 0;
bool symmetryTokens = false;
double width = 0.0;
double height = 0.0;
_tokenize ();
if ( _tokens.size() < 1 )
throw Exception("Bookshelf::Parse(): @%d, Invalid Node line in <.nodes>.",_lineno);
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; }
symmetryTokens = false;
}
if ( std::string("terminal").compare(_tokens[itoken]) == 0 ) { terminal = true; continue; }
if ( std::string(":").compare(_tokens[itoken]) == 0 ) { symmetryTokens = true; continue; }
//std::cerr << " <X Y>" << std::endl;
width = toDouble ( _tokens[itoken] );
if ( ++itoken == _tokens.size() )
throw Exception("Bookshelf::Parse(): @%d, Invalid Node line in <.nodes>.",_lineno);
height = toDouble ( _tokens[itoken] );
}
_circuit->addNode ( new Node(_tokens[0],width,height,symmetry,terminal) );
// std::cerr << "name:" << _tokens[0]
// << " " << width
// << " " << height
// << " " << boolalpha << terminal
// << " : " << symmetry
// << std::endl;
}
void Parser::_parseNodes ( const bfs::path& nodesPath )
{
_circuit->setNodesName ( nodesPath.string());
_state = NodesFormatRevision;
_openStream ( nodesPath );
_circuit->setFlags ( Circuit::Nodes );
while ( not _stream.eof() ) {
_readLine ();
if ( _state == NodesFormatRevision ) {
_parseFormatRevision ( "nodes" );
_state = NodesNumNodes;
continue;
} else {
if ( _isComment() ) continue;
switch ( _state ) {
case NodesNumNodes:
_circuit->setNumNodes(_parseNum("nodes","NumNodes")); _state = NodesNumTerminals; break;
case NodesNumTerminals:
_circuit->setNumTerminals(_parseNum("nodes","NumTerminals")); _state = NodesNode; break;
case NodesNode:
_parseNodesNode(); break;
}
}
}
_closeStream ();
_state = 0;
}
void Parser::_parseNetsNetDegree ()
{
//std::cerr << _buffer << std::endl;
_tokenize ();
if ( (_tokens.size() < 3 )
or (std::string("NetDegree").compare(_tokens[0]) != 0)
or (std::string(":" ).compare(_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid NetDegree in <.nets>.",_lineno);
std::string name;
if ( _tokens.size() >= 4 ) name = _tokens[3];
_net = new Net ( _circuit, (size_t)toLong(_tokens[2]), name );
}
void Parser::_parseNetsPin ()
{
unsigned int direction = Direction::Disabled;
double x = 0;
double y = 0;
bool tokenDirection = true;
_tokenize ();
if ( _tokens.size() < 1 )
throw Exception("Bookshelf::Parse(): @%d, Invalid Net line in <.nets>.",_lineno);
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 ( direction != Direction::Disabled ) {
tokenDirection = false;
continue;
}
}
if ( std::string(":").compare(_tokens[itoken]) == 0 ) {
tokenDirection = false;
if ( ++itoken == _tokens.size() )
throw Exception("Bookshelf::Parse(): @%d, Invalid Net line in <.nets>.",_lineno);
x = toDouble ( _tokens[itoken] );
if ( ++itoken == _tokens.size() )
throw Exception("Bookshelf::Parse(): @%d, Invalid Net line in <.nets>.",_lineno);
y = toDouble ( _tokens[itoken] );
break;
}
}
Node* node = _circuit->getNode ( _tokens[0] );
if ( node == NULL )
throw Exception("Bookshelf::Parse(): @%d, Invalid Node name line in <.nets>.",_lineno);
new Pin ( _circuit, node, _net, x, y, direction );
// std::cerr << "name:" << _tokens[0]
// << " " << x
// << " " << y
// << " " << boolalpha << terminal
// << " : " << symmetry
// << std::endl;
}
void Parser::_parseNets ( const bfs::path& netsPath )
{
_circuit->setNetsName ( netsPath.string());
_state = NetsFormatRevision;
_openStream ( netsPath );
_circuit->setFlags ( Circuit::Nets );
while ( not _stream.eof() ) {
_readLine ();
if ( _state == NetsFormatRevision ) {
_parseFormatRevision ( "nets" );
_state = NetsNumNets;
continue;
} else {
if ( _isComment() ) continue;
switch ( _state ) {
case NetsNumNets:
_circuit->setNumNets(_parseNum("nets","NumNets")); _state = NetsNumPins; break;
case NetsNumPins:
_circuit->setNumPins(_parseNum("nets","NumPins")); _state = NetsDegree; break;
case NetsDegree:
_parseNetsNetDegree (); _state = NetsPin; break;
case NetsPin:
_parseNetsPin ();
if ( _net->getDegree() == _net->getPins().size() ) _state = NetsDegree;
break;
}
}
}
if ( _net->getDegree() > _net->getPins().size() )
throw Exception("Bookshelf::parse(): @EOF, missing pins.");
_closeStream ();
_circuit->resolveNames ();
_state = 0;
}
void Parser::_parseWts ( const bfs::path& nodesPath )
{
//_circuit->setWtsName ( wtsPath.string());
//std::cout << "Parser::_parseWts()" << std::endl;
}
void Parser::_parseSclCoreRow ()
{
_tokenize ();
if ( (_tokens.size() < 2)
or (std::string("CoreRow" ).compare(_tokens[0]) != 0)
or (std::string("Horizontal").compare(_tokens[1]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow line in <.scl>.",_lineno);
_row = new Row ();
_circuit->addRow ( _row );
}
void Parser::_parseSclSiteorient ()
{
_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);
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);
}
void Parser::_parseSclSitesymmetry ()
{
_tokenize ();
if ( (_tokens.size() < 3)
or (std::string("Sitesymmetry").compare(_tokens[0]) != 0)
or (std::string(":" ).compare(_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);
}
void Parser::_parseSclSubrowOrigin ()
{
_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) )
throw Exception("Bookshelf::Parse(): @%d, Invalid Row SubrowOrigin line in <.scl>.",_lineno);
_row->setSubrowOrigin ( toDouble(_tokens[2]) );
_row->setNumsites ( toDouble(_tokens[5]) );
}
void Parser::_parseSclCorerowEnd ()
{
_tokenize ();
if ( (_tokens.size() < 1)
or (std::string("End").compare(_tokens[0]) != 0) )
throw Exception("Bookshelf::Parse(): @%d, Invalid CoreRow end line in <.scl>.",_lineno);
_row = NULL;
}
void Parser::_parseScl ( const bfs::path& sclPath )
{
_circuit->setSclName ( sclPath.string());
_state = SclFormatRevision;
_openStream ( sclPath );
_circuit->setFlags ( Circuit::Scl );
while ( not _stream.eof() and (_state != SclFinish) ) {
_readLine ();
if ( _state == SclFormatRevision ) {
_parseFormatRevision ( "scl" );
_state = SclNumRows;
continue;
} else {
if ( _isComment() ) continue;
switch ( _state ) {
case SclNumRows:
_circuit->setNumRows(_parseNum("scl","NumRows")); _state = SclCoreRow; break;
case SclCoreRow:
_parseSclCoreRow(); _state = SclCoordinate; break;
case SclCoordinate:
_row->setCoordinate(_parseNum ("scl","Coordinate")); _state = SclHeight; break;
case SclHeight:
_row->setHeight(_parseNum ("scl","Height")); _state = SclSitewidth; break;
case SclSitewidth:
_row->setSitewidth(_parseNum ("scl","Sitewidth")); _state = SclSitespacing; break;
case SclSitespacing:
_row->setSitespacing(_parseNum ("scl","Sitespacing")); _state = SclSiteorient; break;
case SclSiteorient:
_parseSclSiteorient(); _state = SclSitesymmetry; break;
case SclSitesymmetry:
_parseSclSitesymmetry(); _state = SclSubrowOrigin; break;
case SclSubrowOrigin:
_parseSclSubrowOrigin(); _state = SclCorerowEnd; break;
case SclCorerowEnd:
_parseSclCorerowEnd ();
if ( _circuit->getRows().size() >= _circuit->getNumRows() ) {
_state = SclFinish;
} else {
_state = SclCoreRow;
}
break;
}
}
}
_closeStream ();
_state = 0;
}
void Parser::_parsePlNodePlace ()
{
unsigned int orientation = Orientation::N;
bool orientationToken = false;
double x = 0;
double y = 0;
_tokenize ();
if ( _tokens.size() < 3 )
throw Exception("Bookshelf::Parse(): @%d, Invalid Node Placement line in <.pl>.",_lineno);
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; }
break;
}
if ( std::string(":").compare(_tokens[itoken]) == 0 ) { orientationToken = true; continue; }
//std::cerr << " <X Y>" << std::endl;
x = toDouble ( _tokens[itoken] );
if ( ++itoken == _tokens.size() )
throw Exception("Bookshelf::Parse(): @%d, Invalid Node line in <.pl>.",_lineno);
y = toDouble ( _tokens[itoken] );
}
Node* node = _circuit->getNode ( _tokens[0] );
if ( node == NULL )
throw Exception("Bookshelf::Parse(): @%d, Unknown Node <%s> line in <.pl>.",_lineno,_tokens[0]);
node->setX ( x );
node->setY ( y );
node->setOrientation ( orientation );
}
void Parser::_parsePl ( const bfs::path& plPath )
{
_circuit->setPlName ( plPath.string());
_state = PlFormatRevision;
_openStream ( plPath );
_circuit->setFlags ( Circuit::Pl );
while ( not _stream.eof() ) {
_readLine ();
if ( _state == PlFormatRevision ) {
_parseFormatRevision ( "pl" );
_state = PlNodePlace;
continue;
} else {
if ( _isComment() ) continue;
_parsePlNodePlace ();
}
}
}
Circuit* Parser::parse ( std::string designName, unsigned int flags )
{
bfs::path auxPath ( designName+".aux" );
if ( not bfs::exists(auxPath) ) {
throw Exception ( "%s .aux file not found.", auxPath.string().c_str() );
}
_circuit = new Circuit ();
_circuit->setDesignName ( designName );
std::cout << " o Reading Bookshelf: <" << auxPath.string() << ">." << std::endl;
_openStream ( auxPath );
_readLine ();
_closeStream ();
_tokenize ();
if ( std::string(":").compare(_tokens[1]) == 0 ) {
// Re-ordering files: .nodes, .nets, .wts, .scl, .pl.
std::string ordereds [5];
for ( size_t extension=0 ; extension<5 ; ++extension ) {
for ( size_t i=2 ; i<_tokens.size() ; ++i ) {
std::string file ( _tokens[i] );
size_t iext = file.rfind ( '.' );
switch ( extension ) {
case 0:
if ( (file.compare(iext,6,".nodes") == 0) and (flags & Circuit::Nodes) )
ordereds[0] = _tokens[i];
break;
case 1:
if ( (file.compare(iext,5,".nets") == 0) and (flags & Circuit::Nets) )
ordereds[1] = _tokens[i];
break;
case 2:
if ( (file.compare(iext,4,".wts") == 0) and (flags & Circuit::Wts) )
ordereds[2] = _tokens[i];
break;
case 3:
if ( (file.compare(iext,4,".scl") == 0) and (flags & Circuit::Scl) )
ordereds[3] = _tokens[i];
break;
case 4:
if ( (file.compare(iext,3,".pl") == 0) and (flags & Circuit::Pl) )
ordereds[4] = _tokens[i];
break;
}
if ( not ordereds[extension].empty() ) break;
}
}
if ( ordereds[0].empty() )
throw Exception("Bookshelf::Parser(): .aux file do not contains <.nodes>.");
if ( ordereds[1].empty() )
throw Exception("Bookshelf::Parser(): .aux file do not contains <.nets>.");
for ( size_t iext=0 ; iext<5 ; ++iext ) {
if ( ordereds[iext].empty() ) continue;
bfs::path slotPath ( ordereds[iext] );
if ( bfs::exists(slotPath) ) {
std::cout << " o Reading <" << slotPath.string() << ">" << std::endl;
switch ( iext ) {
case 0: _parseNodes ( slotPath ); break;
case 1: _parseNets ( slotPath ); break;
case 2: _parseWts ( slotPath ); break;
case 3: _parseScl ( slotPath ); break;
case 4: _parsePl ( slotPath ); break;
}
} else {
Exception e ( "Bookshelf::parser(): Slot file <%s> not found", slotPath.string().c_str() );
if ( iext < 2 ) throw e;
else std::cerr << e.what() << std::endl;
}
}
} else
throw Exception ( "Syntax error in .aux file." );
return _circuit;
}
} // End of Bookself namespace.

View File

@ -0,0 +1,72 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Pin.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "vlsisapd/bookshelf/Node.h"
#include "vlsisapd/bookshelf/Pin.h"
#include "vlsisapd/bookshelf/Net.h"
#include "vlsisapd/bookshelf/Circuit.h"
namespace Bookshelf {
Pin::Pin ( Circuit* circuit
, Node* node
, Net* net
, double x
, double y
, unsigned int direction
)
: _id (circuit->getPinId())
, _x (x)
, _y (y)
, _direction(direction)
, _node (node)
, _net (net)
{
_node->addPin ( this );
_net ->addPin ( this );
}
void Pin::writeToStream ( std::ostream& o )
{
o << std::setw(10) << std::right << _node->getName();
if ( _direction != Direction::Disabled ) {
if ( _direction == Direction::Bidirectional ) o << " B";
else {
if ( _direction & Direction::Input ) o << " I";
if ( _direction & Direction::Output ) o << " O";
}
}
if ( (_x != 0.0) or (_y != 0) ) {
o << " : " << std::setw(5) << std::right << _x << " " << std::setw(5) << std::right << _y;
}
o << std::endl;
}
} // End of Bookshelf namespace.

View File

@ -0,0 +1,67 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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++ Module : "./Row.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "vlsisapd/bookshelf/Exception.h"
#include "vlsisapd/bookshelf/Row.h"
namespace Bookshelf {
void Row::writeToStream ( std::ostream& o )
{
o << "CoreRow Horizontal\n";
o << " Coordinate :" << std::setw(10) << std::right << _coordinate << "\n";
o << " Height :" << std::setw(10) << std::right << _height << "\n";
o << " Sitewidth :" << std::setw(10) << std::right << _sitewidth << "\n";
o << " Sitespacing :" << std::setw(10) << std::right << _sitespacing << "\n";
o << " Siteorient : ";
if ( _siteorient == Orientation::Disabled ) o << " N";
else if ( _siteorient == Orientation::N ) o << " N";
else if ( _siteorient == Orientation::E ) o << " E";
else if ( _siteorient == Orientation::S ) o << " S";
else if ( _siteorient == Orientation::W ) o << " W";
else if ( _siteorient == Orientation::FN ) o << " FN";
else if ( _siteorient == Orientation::FE ) o << " FE";
else if ( _siteorient == Orientation::FS ) o << " FS";
else if ( _siteorient == Orientation::FW ) o << " FW";
o << "\n";
o << " Sitesymmetry : ";
if ( _sitesymmetry == Symmetry::Disabled ) o << " N";
else if ( _sitesymmetry == Symmetry::R90 ) o << " R90";
else if ( _sitesymmetry == Symmetry::X ) o << " X";
else if ( _sitesymmetry == Symmetry::Y ) o << " Y";
o << "\n";
o << " SubrowOrigin :" << std::setw(10) << std::right << _subrowOrigin;
o << " Numsites :" << std::setw(10) << std::right << _numsites << "\n";
o << "End" << std::endl;
}
} // End of Bookshelf namespace.

View File

@ -0,0 +1,158 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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/Circuit.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_CIRCUIT__
#define __VLSISAPD_BOOKSHELF_CIRCUIT__
#include <iostream>
#include <string>
#include <map>
#include <vector>
namespace Bookshelf {
class Node;
class Net;
class Row;
class Circuit {
public:
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
);
void drive ( std::string directory
, unsigned int flags =AllSlots
);
public:
Circuit ();
~Circuit ();
inline bool hasNets () const;
inline bool hasNodes () const;
inline bool hasWts () const;
inline bool hasScl () const;
inline bool hasPl () const;
bool hasAutomaticName ( Net* );
inline const std::string& getDesignName () const;
inline const std::string& getNodesName () const;
inline const std::string& getNetsName () const;
inline const std::string& getWtsName () const;
inline const std::string& getSclName () const;
inline const std::string& getPlName () const;
inline size_t getNumNodes () const;
inline size_t getNumTerminals () const;
inline size_t getNumNets () const;
inline size_t getNumPins () const;
inline size_t getNumRows () const;
Node* getNode ( const std::string& ) const;
Net* getNet ( const std::string& ) const;
inline std::map<std::string,Node*>& getNodes ();
inline std::vector<Net*>& getNets ();
inline std::vector<Row*>& getRows ();
std::string getAutomaticName ( size_t id=0 );
inline size_t getPinId ();
bool check () const;
inline void setFlags ( long );
inline void setDesignName ( const std::string& );
inline void setNodesName ( const std::string& );
inline void setNetsName ( const std::string& );
inline void setWtsName ( const std::string& );
inline void setSclName ( const std::string& );
inline void setPlName ( const std::string& );
inline void setNumNodes ( size_t );
inline void setNumTerminals ( size_t );
inline void setNumNets ( size_t );
inline void setNumPins ( size_t );
inline void setNumRows ( size_t );
void addNode ( Node* );
void addNet ( Net* );
void addRow ( Row* );
void resolveNames ();
void writeNodesToStream ( std::ostream& );
void writeNetsToStream ( std::ostream& );
void writeSclToStream ( std::ostream& );
void writePlToStream ( std::ostream& );
private:
std::string _designName;
std::string _nodesName;
std::string _netsName;
std::string _wtsName;
std::string _sclName;
std::string _plName;
long _flags;
size_t _numNodes;
size_t _numTerminals;
size_t _numNets;
size_t _numPins;
size_t _maxPinId;
size_t _numRows;
std::map<std::string,Node*> _nodes;
std::map<std::string,Net*> _netsByName;
std::vector<Net*> _nets;
std::vector<Row*> _rows;
};
inline bool Circuit::hasNets () const { return _flags&Nets; }
inline bool Circuit::hasNodes () const { return _flags&Nodes; }
inline bool Circuit::hasWts () const { return _flags&Wts; }
inline bool Circuit::hasScl () const { return _flags&Scl; }
inline bool Circuit::hasPl () const { return _flags&Pl; }
inline const std::string& Circuit::getDesignName () const { return _designName; };
inline const std::string& Circuit::getNodesName () const { return _nodesName; };
inline const std::string& Circuit::getNetsName () const { return _netsName; };
inline const std::string& Circuit::getWtsName () const { return _wtsName; };
inline const std::string& Circuit::getSclName () const { return _sclName; };
inline const std::string& Circuit::getPlName () const { return _plName; };
inline size_t Circuit::getNumNodes () const { return _numNodes; }
inline size_t Circuit::getNumTerminals () const { return _numTerminals; }
inline size_t Circuit::getNumNets () const { return _numNets; }
inline size_t Circuit::getNumPins () const { return _numPins; }
inline size_t Circuit::getNumRows () const { return _numRows; }
inline std::map<std::string,Node*>& Circuit::getNodes () { return _nodes; }
inline std::vector<Net*>& Circuit::getNets () { return _nets; }
inline std::vector<Row*>& Circuit::getRows () { return _rows; }
inline size_t Circuit::getPinId () { return _maxPinId++; }
inline void Circuit::setFlags ( long flags ) { _flags |= flags; }
inline void Circuit::setDesignName ( const std::string& name ) { _designName=name; };
inline void Circuit::setNodesName ( const std::string& name ) { _nodesName=name; };
inline void Circuit::setNetsName ( const std::string& name ) { _netsName=name; };
inline void Circuit::setWtsName ( const std::string& name ) { _wtsName=name; };
inline void Circuit::setSclName ( const std::string& name ) { _sclName=name; };
inline void Circuit::setPlName ( const std::string& name ) { _plName=name; };
inline void Circuit::setNumNodes ( size_t value ) { _numNodes=value; }
inline void Circuit::setNumTerminals ( size_t value ) { _numTerminals=value; }
inline void Circuit::setNumNets ( size_t value ) { _numNets=value; }
inline void Circuit::setNumPins ( size_t value ) { _numPins=value; }
inline void Circuit::setNumRows ( size_t value ) { _numRows=value; }
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_CIRCUIT__

View File

@ -0,0 +1,54 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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/Exception.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_EXCEPTION__
#define __VLSISAPD_BOOKSHELF_EXCEPTION__
#include <string>
#include <exception>
namespace Bookshelf {
class Exception : public std::exception {
public:
Exception ( const std::string& ) throw();
Exception ( const char* format, ... ) throw();
Exception ( const Exception& ) throw();
virtual ~Exception () throw();
public:
virtual const char* what () const throw ();
private:
static std::string _addHeader ( const char* );
private:
std::string _message;
};
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_EXCEPTION__

View File

@ -0,0 +1,75 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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/Net.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_NET__
#define __VLSISAPD_BOOKSHELF_NET__
#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
namespace Bookshelf {
class Pin;
class Circuit;
class Net {
public:
static void resetMapName ();
public:
Net ( Circuit*, size_t degree, const std::string& name );
~Net ();
inline Circuit* getCircuit () const;
inline size_t getId () const;
inline size_t getDegree () const;
inline const std::string& getName () const;
inline std::vector<Pin*>& getPins ();
void addPin ( Pin* );
inline void setName ( const std::string& );
void writeToStream ( std::ostream& );
private:
Circuit* _circuit;
size_t _id;
size_t _degree;
std::string _name;
std::vector<Pin*> _pins;
};
inline Circuit* Net::getCircuit () const { return _circuit; }
inline size_t Net::getId () const { return _id; }
inline size_t Net::getDegree () const { return _degree; }
inline const std::string& Net::getName () const { return _name; }
inline std::vector<Pin*>& Net::getPins () { return _pins; }
inline void Net::setName ( const std::string& name ) { _name=name; }
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_NET__

View File

@ -0,0 +1,131 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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/Node.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_NODE__
#define __VLSISAPD_BOOKSHELF_NODE__
#include <string>
#include <iostream>
#include <iomanip>
#include <map>
namespace Bookshelf {
class Pin;
class Symmetry {
public:
enum Code { Disabled=0x0, X=0x1, Y=0x2, R90=0x4 };
};
class Orientation {
public:
enum Code { Disabled=0, N, E, S, W, FN, FS, FW, FE };
};
class Node {
public:
inline Node ( const std::string& name
, double width =0.0
, double height =0.0
, unsigned int symmetry=Symmetry::Disabled
, bool terminal=false );
inline bool isTerminal () const;
inline const std::string& getName () const;
inline double getWidth () const;
inline double getHeight () const;
inline double getX () const;
inline double getY () const;
inline unsigned int getSymmetry () const;
inline unsigned int getOrientation () const;
Pin* getPin ( size_t id ) const;
inline std::map<size_t,Pin*>& getPins ();
void addPin ( Pin* );
inline void setX ( double );
inline void setY ( double );
inline void setOrientation ( unsigned int );
void writeToStream ( std::ostream&, unsigned int flags );
friend std::ostream& operator<< ( std::ostream&, const Node* );
private:
std::string _name;
double _width;
double _height;
unsigned int _symmetry;
double _x;
double _y;
unsigned int _orientation;
bool _terminal;
std::map<size_t,Pin*> _pins;
};
inline Node::Node ( const std::string& name
, double width
, double height
, unsigned int symmetry
, bool terminal
)
: _name (name)
, _width (width)
, _height (height)
, _symmetry (symmetry)
, _x (0.0)
, _y (0.0)
, _orientation(Orientation::Disabled)
, _terminal (terminal)
{
// std::cerr << "Node::Node() "
// << (void*)this
// << " - <"
// << name
// << " " << _width
// << " " << _height
// << " " << std::boolalpha << _terminal
// << " :" << _symmetry
// << ">." << std::endl;
}
inline bool Node::isTerminal () const { return _terminal; }
inline const std::string& Node::getName () const { return _name; }
inline double Node::getWidth () const { return _width; }
inline double Node::getHeight () const { return _height; }
inline double Node::getX () const { return _x; }
inline double Node::getY () const { return _y; }
inline unsigned int Node::getSymmetry () const { return _symmetry; }
inline unsigned int Node::getOrientation () const { return _orientation; }
inline std::map<size_t,Pin*>& Node::getPins () { return _pins; }
inline void Node::setX ( double x ) { _x=x; }
inline void Node::setY ( double y ) { _y=y; }
inline void Node::setOrientation ( unsigned int orient ) { _orientation=orient; }
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_NODE__

View File

@ -0,0 +1,93 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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/Parser.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_PARSER__
#define __VLSISAPD_BOOKSHELF_PARSER__
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
namespace bfs = boost::filesystem;
#include <string>
#include <iostream>
#include <vector>
namespace Bookshelf {
class Parser {
public:
enum Flag { Comment=0x1, ExtraDatas=0x2 };
public:
Parser ();
Circuit* parse ( std::string designName, unsigned int flags );
private:
bool _openStream ( const bfs::path& );
void _closeStream ();
char* _readLine ();
void _tokenize ();
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 );
void _parseNodes ( const bfs::path& );
void _parseNodesNode ();
void _parseNets ( const bfs::path& );
void _parseNetsNetDegree ();
void _parseNetsPin ();
void _parseWts ( const bfs::path& );
void _parseScl ( const bfs::path& );
void _parseSclCoreRow ();
void _parseSclSiteorient ();
void _parseSclSitesymmetry ();
void _parseSclSubrowOrigin ();
void _parseSclCorerowEnd ();
void _parsePl ( const bfs::path& );
void _parsePlNodePlace ();
inline bool _isComment () const;
inline bool _hasExtraDatas () const;
private:
enum Misc { BufferSize=4096 };
private:
size_t _lineno;
bfs::ifstream _stream;
char _buffer[BufferSize];
std::vector<char*> _tokens;
unsigned int _flags;
int _state;
Net* _net;
Row* _row;
Circuit* _circuit;
};
inline bool Parser::_isComment () const { return _flags&Comment; }
inline bool Parser::_hasExtraDatas () const { return _flags&ExtraDatas; }
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_PARSER__

View File

@ -0,0 +1,84 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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
#ifndef __VLSISAPD_BOOKSHELF_PIN__
#define __VLSISAPD_BOOKSHELF_PIN__
#include <string>
#include <iostream>
#include <iomanip>
namespace Bookshelf {
class Node;
class Net;
class Circuit;
class Direction {
public:
enum Codes { Disabled=0x0, Input=0x1, Output=0x2, Bidirectional=Input|Output };
};
class Pin {
public:
Pin ( Circuit*
, Node*
, Net*
, double x =0.0
, double y =0.0
, unsigned int direction=Direction::Disabled
);
inline size_t getId () const;
inline Node* getNode () const;
inline Net* getNet () const;
inline double getX () const;
inline double getY () const;
inline unsigned int getDirection () const;
void writeToStream ( std::ostream& );
private:
size_t _id;
double _x;
double _y;
unsigned int _direction;
Node* _node;
Net* _net;
};
inline size_t Pin::getId () const { return _id; }
inline Net* Pin::getNet () const { return _net; }
inline double Pin::getX () const { return _x; }
inline double Pin::getY () const { return _y; }
inline unsigned int Pin::getDirection () const { return _direction; }
inline Node* Pin::getNode () const { return _node; }
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_PIN__

View File

@ -0,0 +1,102 @@
// -*- C++ -*-
//
// This file is part of the VSLSI Stand-Alone Software.
// Copyright (c) UPMC/LIP6 2008-2010, 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/Row.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __VLSISAPD_BOOKSHELF_ROW__
#define __VLSISAPD_BOOKSHELF_ROW__
#include <string>
#include <iostream>
#include "vlsisapd/bookshelf/Node.h"
namespace Bookshelf {
class Row {
public:
inline Row ();
inline double getCoordinate () const;
inline double getHeight () const;
inline double getSitewidth () const;
inline double getSitespacing () const;
inline unsigned int getSitesymmetry () const;
inline unsigned int getSiteorient () const;
inline double getSubrowOrigin () const;
inline double getNumsites () const;
inline void setCoordinate ( double );
inline void setHeight ( double );
inline void setSitewidth ( double );
inline void setSitespacing ( double );
inline void setSitesymmetry ( unsigned int );
inline void setSiteorient ( unsigned int );
inline void setSubrowOrigin ( double );
inline void setNumsites ( double );
void writeToStream ( std::ostream& );
private:
double _coordinate;
double _height;
double _sitewidth;
double _sitespacing;
unsigned int _sitesymmetry;
unsigned int _siteorient;
double _subrowOrigin;
double _numsites;
};
inline Row::Row ()
: _coordinate (0.0)
, _height (0.0)
, _sitewidth (0.0)
, _sitespacing (0.0)
, _sitesymmetry(Symmetry::Disabled)
, _siteorient (Orientation::Disabled)
, _subrowOrigin(0.0)
, _numsites (0.0)
{ }
inline double Row::getCoordinate () const { return _coordinate; }
inline double Row::getHeight () const { return _height; }
inline double Row::getSitewidth () const { return _sitewidth; }
inline double Row::getSitespacing () const { return _sitespacing; }
inline unsigned int Row::getSitesymmetry () const { return _sitesymmetry; }
inline unsigned int Row::getSiteorient () const { return _siteorient; }
inline double Row::getSubrowOrigin () const { return _subrowOrigin; }
inline double Row::getNumsites () const { return _numsites; }
inline void Row::setCoordinate (double value) { _coordinate=value; }
inline void Row::setHeight (double value) { _height=value; }
inline void Row::setSitewidth (double value) { _sitewidth=value; }
inline void Row::setSitespacing (double value) { _sitespacing=value; }
inline void Row::setSitesymmetry (unsigned int value) { _sitesymmetry=value; }
inline void Row::setSiteorient (unsigned int value) { _siteorient=value; }
inline void Row::setSubrowOrigin (double value) { _subrowOrigin=value; }
inline void Row::setNumsites (double value) { _numsites=value; }
} // End of Bookshelf namespace.
#endif // __VLSISAPD_BOOKSHELF_ROW__