From dd405e619f4a1059c2e007528a33591aecf00fa5 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 18 Aug 2010 20:35:50 +0000 Subject: [PATCH] * ./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. --- vlsisapd/cmake_modules/FindVLSISAPD.cmake | 5 + vlsisapd/src/CMakeLists.txt | 1 + vlsisapd/src/bookshelf/CMakeLists.txt | 1 + vlsisapd/src/bookshelf/src/Bookshelf.cpp | 52 ++ .../src/bookshelf/src/BookshelfTkMain.cpp | 173 +++++ vlsisapd/src/bookshelf/src/CMakeLists.txt | 32 + vlsisapd/src/bookshelf/src/Circuit.cpp | 280 ++++++++ vlsisapd/src/bookshelf/src/Exception.cpp | 73 ++ vlsisapd/src/bookshelf/src/Main.cpp | 117 +++ vlsisapd/src/bookshelf/src/Net.cpp | 75 ++ vlsisapd/src/bookshelf/src/Node.cpp | 111 +++ vlsisapd/src/bookshelf/src/Parser.cpp | 676 ++++++++++++++++++ vlsisapd/src/bookshelf/src/Pin.cpp | 72 ++ vlsisapd/src/bookshelf/src/Row.cpp | 67 ++ .../src/vlsisapd/bookshelf/Circuit.h | 158 ++++ .../src/vlsisapd/bookshelf/Exception.h | 54 ++ .../bookshelf/src/vlsisapd/bookshelf/Net.h | 75 ++ .../bookshelf/src/vlsisapd/bookshelf/Node.h | 131 ++++ .../bookshelf/src/vlsisapd/bookshelf/Parser.h | 93 +++ .../bookshelf/src/vlsisapd/bookshelf/Pin.h | 84 +++ .../bookshelf/src/vlsisapd/bookshelf/Row.h | 102 +++ 21 files changed, 2432 insertions(+) create mode 100644 vlsisapd/src/bookshelf/CMakeLists.txt create mode 100644 vlsisapd/src/bookshelf/src/Bookshelf.cpp create mode 100644 vlsisapd/src/bookshelf/src/BookshelfTkMain.cpp create mode 100644 vlsisapd/src/bookshelf/src/CMakeLists.txt create mode 100644 vlsisapd/src/bookshelf/src/Circuit.cpp create mode 100644 vlsisapd/src/bookshelf/src/Exception.cpp create mode 100644 vlsisapd/src/bookshelf/src/Main.cpp create mode 100644 vlsisapd/src/bookshelf/src/Net.cpp create mode 100644 vlsisapd/src/bookshelf/src/Node.cpp create mode 100644 vlsisapd/src/bookshelf/src/Parser.cpp create mode 100644 vlsisapd/src/bookshelf/src/Pin.cpp create mode 100644 vlsisapd/src/bookshelf/src/Row.cpp create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Exception.h create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Net.h create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h create mode 100644 vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h diff --git a/vlsisapd/cmake_modules/FindVLSISAPD.cmake b/vlsisapd/cmake_modules/FindVLSISAPD.cmake index 4f19391c..884303f1 100644 --- a/vlsisapd/cmake_modules/FindVLSISAPD.cmake +++ b/vlsisapd/cmake_modules/FindVLSISAPD.cmake @@ -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}) diff --git a/vlsisapd/src/CMakeLists.txt b/vlsisapd/src/CMakeLists.txt index 4b304fc9..cbcb357f 100644 --- a/vlsisapd/src/CMakeLists.txt +++ b/vlsisapd/src/CMakeLists.txt @@ -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) diff --git a/vlsisapd/src/bookshelf/CMakeLists.txt b/vlsisapd/src/bookshelf/CMakeLists.txt new file mode 100644 index 00000000..4b7537b5 --- /dev/null +++ b/vlsisapd/src/bookshelf/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY(src) diff --git a/vlsisapd/src/bookshelf/src/Bookshelf.cpp b/vlsisapd/src/bookshelf/src/Bookshelf.cpp new file mode 100644 index 00000000..783ebfb8 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Bookshelf.cpp @@ -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 +#include +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. diff --git a/vlsisapd/src/bookshelf/src/BookshelfTkMain.cpp b/vlsisapd/src/bookshelf/src/BookshelfTkMain.cpp new file mode 100644 index 00000000..7c8775d9 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/BookshelfTkMain.cpp @@ -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 +#include +#include +using namespace std; + +#include +namespace boptions = boost::program_options; + +#include +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& nodes = circuit->getNodes(); + map::iterator inode = nodes.begin(); + for ( ; inode != nodes.end() ; ++inode ) { + cout << "NODE:" << (*inode).second->getName() << endl; + map& pins = (*inode).second->getPins(); + map::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& nodes = circuit->getNodes(); + map::iterator inode = nodes.begin(); + for ( ; inode != nodes.end() ; ++inode ) { + Node* node = (*inode).second; + + map& pins = node->getPins(); + map::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& 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 ; irowsetNumsites ( numsites ); + } + double deltaRowCoordinate = rows[rows.size()-1]->getCoordinate(); + + for ( size_t irow=0 ; irowsetCoordinate ( 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() + , "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::parse(arguments["aux"].as()) ); + + 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; +} diff --git a/vlsisapd/src/bookshelf/src/CMakeLists.txt b/vlsisapd/src/bookshelf/src/CMakeLists.txt new file mode 100644 index 00000000..8b3a838c --- /dev/null +++ b/vlsisapd/src/bookshelf/src/CMakeLists.txt @@ -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 ) + diff --git a/vlsisapd/src/bookshelf/src/Circuit.cpp b/vlsisapd/src/bookshelf/src/Circuit.cpp new file mode 100644 index 00000000..13dd7209 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Circuit.cpp @@ -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 +#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::iterator inode = _nodes.begin(); + for ( ; inode != _nodes.end() ; ++inode ) + delete (*inode).second; + } + + + Node* Circuit::getNode ( const std::string& name ) const + { + std::map::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::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::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::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::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::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. diff --git a/vlsisapd/src/bookshelf/src/Exception.cpp b/vlsisapd/src/bookshelf/src/Exception.cpp new file mode 100644 index 00000000..5125fcde --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Exception.cpp @@ -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 +#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. diff --git a/vlsisapd/src/bookshelf/src/Main.cpp b/vlsisapd/src/bookshelf/src/Main.cpp new file mode 100644 index 00000000..85340503 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Main.cpp @@ -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 +#include +using namespace std; + +#include +namespace boptions = boost::program_options; + +#include +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() + , "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::parse(arguments["aux"].as()) ); + + circuit->check (); + + vector& rows = circuit->getRows (); + for ( size_t irow=0 ; irowsetNumsites ( 1096.0 ); + } + + size_t rowAddition = 40; + for ( size_t irow=0 ; irowsetCoordinate ( 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()+"square.scl" ); + + circuit->drive ( ".", Circuit::Scl ); + + // map& nodes = circuit->getNodes(); + // map::iterator inode = nodes.begin(); + // for ( ; inode != nodes.end() ; ++inode ) { + // cerr << "NODE:" << (*inode).second->getName() << endl; + // map& pins = (*inode).second->getPins(); + // map::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; +} diff --git a/vlsisapd/src/bookshelf/src/Net.cpp b/vlsisapd/src/bookshelf/src/Net.cpp new file mode 100644 index 00000000..376375c8 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Net.cpp @@ -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::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::iterator ipin = _pins.begin(); + for ( ; ipin != _pins.end() ; ++ipin ) + (*ipin)->writeToStream ( o ); + } + + +} // End of Bookshelf namespace. diff --git a/vlsisapd/src/bookshelf/src/Node.cpp b/vlsisapd/src/bookshelf/src/Node.cpp new file mode 100644 index 00000000..dc8a79fe --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Node.cpp @@ -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::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 << "_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. diff --git a/vlsisapd/src/bookshelf/src/Parser.cpp b/vlsisapd/src/bookshelf/src/Parser.cpp new file mode 100644 index 00000000..31d8f926 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Parser.cpp @@ -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 +#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 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 << " " << 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 << " " << 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. diff --git a/vlsisapd/src/bookshelf/src/Pin.cpp b/vlsisapd/src/bookshelf/src/Pin.cpp new file mode 100644 index 00000000..6472ef9f --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Pin.cpp @@ -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. diff --git a/vlsisapd/src/bookshelf/src/Row.cpp b/vlsisapd/src/bookshelf/src/Row.cpp new file mode 100644 index 00000000..e198b095 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/Row.cpp @@ -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. diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h new file mode 100644 index 00000000..e8b89c54 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Circuit.h @@ -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 +#include +#include +#include + + +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& getNodes (); + inline std::vector& getNets (); + inline std::vector& 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 _nodes; + std::map _netsByName; + std::vector _nets; + std::vector _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& Circuit::getNodes () { return _nodes; } + inline std::vector& Circuit::getNets () { return _nets; } + inline std::vector& 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__ diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Exception.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Exception.h new file mode 100644 index 00000000..737f244d --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Exception.h @@ -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 +#include + + +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__ diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Net.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Net.h new file mode 100644 index 00000000..9c9870c7 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Net.h @@ -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 +#include +#include +#include + + +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& 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 _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& Net::getPins () { return _pins; } + inline void Net::setName ( const std::string& name ) { _name=name; } + + +} // End of Bookshelf namespace. + + +#endif // __VLSISAPD_BOOKSHELF_NET__ diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h new file mode 100644 index 00000000..7687c4d6 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Node.h @@ -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 +#include +#include +#include + + +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& 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 _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& 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__ diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h new file mode 100644 index 00000000..84aecd18 --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Parser.h @@ -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 +#include +namespace bfs = boost::filesystem; + +#include +#include +#include + + +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& ); + 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 _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__ diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h new file mode 100644 index 00000000..6a51acae --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Pin.h @@ -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 +#include +#include + + +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__ diff --git a/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h new file mode 100644 index 00000000..12f3ec1a --- /dev/null +++ b/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf/Row.h @@ -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 +#include +#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__