New liberty parser / driver :
- only c++ (python will follow) - parse and drive examples
This commit is contained in:
parent
446ccd6d58
commit
7f878e6c3c
|
@ -7,11 +7,13 @@
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${VLSISAPD_SOURCE_DIR}/cmake_modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${VLSISAPD_SOURCE_DIR}/cmake_modules/")
|
||||||
|
|
||||||
setup_boost(program_options filesystem python)
|
setup_boost(program_options filesystem python regex)
|
||||||
|
|
||||||
find_package(LibXml2 REQUIRED)
|
find_package(LibXml2 REQUIRED)
|
||||||
find_package(PythonSitePackages REQUIRED)
|
find_package(PythonSitePackages REQUIRED)
|
||||||
find_package(PythonLibs REQUIRED)
|
find_package(PythonLibs REQUIRED)
|
||||||
|
find_package(BISON REQUIRED)
|
||||||
|
find_package(FLEX REQUIRED)
|
||||||
find_package(Doxygen)
|
find_package(Doxygen)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -2,3 +2,4 @@ ADD_SUBDIRECTORY(cif)
|
||||||
ADD_SUBDIRECTORY(agds)
|
ADD_SUBDIRECTORY(agds)
|
||||||
ADD_SUBDIRECTORY(dtr)
|
ADD_SUBDIRECTORY(dtr)
|
||||||
ADD_SUBDIRECTORY(openChams)
|
ADD_SUBDIRECTORY(openChams)
|
||||||
|
ADD_SUBDIRECTORY(liberty)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
ADD_SUBDIRECTORY(cplusplus)
|
||||||
|
#ADD_SUBDIRECTORY(python)
|
||||||
|
|
||||||
|
#INSTALL ( FILES inverter.xml DESTINATION share/doc/coriolis2/examples/vlsisapd/openChams )
|
|
@ -0,0 +1,7 @@
|
||||||
|
INCLUDE_DIRECTORIES ( ${VLSISAPD_SOURCE_DIR}/src/liberty/src )
|
||||||
|
ADD_EXECUTABLE ( driveLiberty driveLiberty.cpp )
|
||||||
|
ADD_EXECUTABLE ( parseLiberty parseLiberty.cpp )
|
||||||
|
TARGET_LINK_LIBRARIES ( driveLiberty liberty )
|
||||||
|
TARGET_LINK_LIBRARIES ( parseLiberty liberty )
|
||||||
|
INSTALL ( TARGETS driveLiberty DESTINATION share/doc/coriolis2/examples/vlsisapd/liberty )
|
||||||
|
INSTALL ( TARGETS parseLiberty DESTINATION share/doc/coriolis2/examples/vlsisapd/liberty )
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include<string.h>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Library.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoad.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoadSelection.h"
|
||||||
|
#include "vlsisapd/liberty/Cell.h"
|
||||||
|
#include "vlsisapd/liberty/Pin.h"
|
||||||
|
#include "vlsisapd/liberty/Timing.h"
|
||||||
|
|
||||||
|
int main ( int argc, char * argv[] ) {
|
||||||
|
LIB::Name libName = LIB::Name("test");
|
||||||
|
LIB::Library* library = new LIB::Library(libName);
|
||||||
|
|
||||||
|
std::string valeur, unit;
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
valeur="0.011"; library->addAttribute(LIB::Name("default_inout_pin_cap"), LIB::Attribute::Double, valeur);
|
||||||
|
valeur="enclosed"; library->addAttribute(LIB::Name("default_wire_load_mode"), LIB::Attribute::String, valeur);
|
||||||
|
valeur="1", unit="ns"; library->addAttribute(LIB::Name("time_unit"), LIB::Attribute::Unit, valeur, unit);
|
||||||
|
valeur="1", unit="pf"; library->addAttribute(LIB::Name("capacitive_load_unit"), LIB::Attribute::Unit, valeur, unit);
|
||||||
|
|
||||||
|
// WireLoads
|
||||||
|
library->addWireLoad(LIB::Name("medium"));
|
||||||
|
LIB::WireLoad* wireLoad = library->getWireLoad(LIB::Name("medium"));
|
||||||
|
valeur="200"; wireLoad->addAttribute(LIB::Name("slope"), LIB::Attribute::Double, valeur);
|
||||||
|
valeur="1"; unit="200"; wireLoad->addAttribute(LIB::Name("fanout_length"), LIB::Attribute::Pair, valeur, unit);
|
||||||
|
|
||||||
|
// WireLoadSelection
|
||||||
|
library->addWireLoadSelection(LIB::Name("medium"));
|
||||||
|
LIB::WireLoadSelection* wireLoadSelection = library->getWireLoadSelection();
|
||||||
|
wireLoadSelection->addWireLoadArea(0, 500, LIB::Name("small"));
|
||||||
|
|
||||||
|
// Cells
|
||||||
|
library->addCell(LIB::Name("inv"));
|
||||||
|
LIB::Cell* cell = library->getCell(LIB::Name("inv"));
|
||||||
|
valeur="1"; cell->addAttribute(LIB::Name("area"), LIB::Attribute::Double, valeur);
|
||||||
|
valeur="inv"; cell->addAttribute(LIB::Name("cell_footprint"), LIB::Attribute::String, valeur);
|
||||||
|
|
||||||
|
LIB::Pin* pin;
|
||||||
|
|
||||||
|
// Pins
|
||||||
|
cell->addPin(LIB::Name("e"));
|
||||||
|
pin = cell->getPin(LIB::Name("e"));
|
||||||
|
valeur="0.008"; pin->addAttribute(LIB::Name("capacitance"), LIB::Attribute::Double, valeur);
|
||||||
|
valeur="input"; pin->addAttribute(LIB::Name("direction"), LIB::Attribute::String, valeur);
|
||||||
|
|
||||||
|
cell->addPin(LIB::Name("s"));
|
||||||
|
pin = cell->getPin(LIB::Name("s"));
|
||||||
|
valeur="i'"; pin->addAttribute(LIB::Name("function"), LIB::Attribute::String, valeur);
|
||||||
|
valeur="output"; pin->addAttribute(LIB::Name("direction"), LIB::Attribute::String, valeur);
|
||||||
|
|
||||||
|
// Timing
|
||||||
|
LIB::Timing * timing;
|
||||||
|
pin->addTiming();
|
||||||
|
timing = pin->getTiming().back();
|
||||||
|
valeur="negative_unate"; timing->addAttribute(LIB::Name("timing_sense"), LIB::Attribute::String, valeur);
|
||||||
|
valeur="e"; timing->addAttribute(LIB::Name("related_pin"), LIB::Attribute::String, valeur);
|
||||||
|
valeur="0.101"; timing->addAttribute(LIB::Name("intrinsic_rise"), LIB::Attribute::Double, valeur);
|
||||||
|
|
||||||
|
|
||||||
|
// Write
|
||||||
|
valeur="test.lib"; library->writeToFile(valeur);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Library.h"
|
||||||
|
|
||||||
|
int main ( int argc, char * argv[] ) {
|
||||||
|
LIB::Library* library = LIB::Library::readFromFile("./sxlib.lib");
|
||||||
|
|
||||||
|
if ( library ) {
|
||||||
|
library->print();
|
||||||
|
} else {
|
||||||
|
cerr << "library is NULL" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// library->writeToFile("./mySxlib.lib");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,3 +8,4 @@ IF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr)
|
||||||
ENDIF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr)
|
ENDIF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr)
|
||||||
ADD_SUBDIRECTORY(bookshelf)
|
ADD_SUBDIRECTORY(bookshelf)
|
||||||
ADD_SUBDIRECTORY(configuration)
|
ADD_SUBDIRECTORY(configuration)
|
||||||
|
ADD_SUBDIRECTORY(liberty)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ADD_SUBDIRECTORY(src)
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
Attribute::Attribute(const Name name, Type type, const std::string& value, const std::string& unit, const std::string& value2) : _name (name), _type(type), _value(value), _unit(unit), _value2(value2) {};
|
||||||
|
|
||||||
|
bool Attribute::valueAsBool() const {
|
||||||
|
if ( _type != Bool )
|
||||||
|
cerr << "[ERROR] Accessing parameter " << _name.getString() << " (type mismatch)." << endl;
|
||||||
|
|
||||||
|
istringstream s ( _value );
|
||||||
|
bool b;
|
||||||
|
s >> boolalpha >> b;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Attribute::valueAsInt() const {
|
||||||
|
if ( _type != Int )
|
||||||
|
cerr << "[ERROR] Accessing parameter " << _name.getString() << " (type mismatch)." << endl;
|
||||||
|
|
||||||
|
istringstream s ( _value );
|
||||||
|
int i;
|
||||||
|
s >> i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Attribute::valueAsDouble() const {
|
||||||
|
if ( (_type != Double) & (_type != Pair) )
|
||||||
|
cerr << "[ERROR] Accessing parameter " << _name.getString() << " (type mismatch)." << endl;
|
||||||
|
|
||||||
|
std::istringstream s ( _value );
|
||||||
|
double d;
|
||||||
|
s >> d;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Attribute::secondValueAsDouble() const {
|
||||||
|
if ( _type != Pair )
|
||||||
|
cerr << "[ERROR] Accessing parameter " << _name.getString() << " (type mismatch)." << endl;
|
||||||
|
|
||||||
|
double d;
|
||||||
|
if(!_value2.empty())
|
||||||
|
{
|
||||||
|
std::istringstream s ( _value2 );
|
||||||
|
s >> d;
|
||||||
|
} else {
|
||||||
|
d = 0;
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Attribute::typeToString(Attribute::Type type) {
|
||||||
|
switch(type) {
|
||||||
|
case Unknown: return "unknown";
|
||||||
|
case String: return "string";
|
||||||
|
case Bool: return "bool";
|
||||||
|
case Int: return "int";
|
||||||
|
case Double: return "double";
|
||||||
|
case Unit: return "unit";
|
||||||
|
case Pair: return "pair";
|
||||||
|
}
|
||||||
|
return "unsupported";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Attribute::write(ofstream &file) {
|
||||||
|
if( (_type == Attribute::String) | (_type == Attribute::Double) ) {
|
||||||
|
if( (_name.getString() == "cell_footprint") | (_name.getString() == "function") | (_name.getString() == "related_pin") | (_name.getString() == "clocked_on") | (_name.getString() == "next_state"))
|
||||||
|
file << _name.getString() << " : \"" << _value << "\";" << endl;
|
||||||
|
else
|
||||||
|
file << _name.getString() << " : " << _value << ";" << endl;
|
||||||
|
} else if(_type == Attribute::Unit) {
|
||||||
|
if( (_name.getString() == "capacitive_load_unit"))
|
||||||
|
file << _name.getString() << "(" << _value << "," << _unit << ");" << endl;
|
||||||
|
else
|
||||||
|
file << _name.getString() << " : \"" << _value << _unit << "\";" << endl;
|
||||||
|
} else if(_type == Attribute::Pair) {
|
||||||
|
file << _name.getString() << "(" << _value << "," << _value2 << ");" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
|
@ -0,0 +1,63 @@
|
||||||
|
|
||||||
|
include_directories ( ${VLSISAPD_SOURCE_DIR}/src/liberty/src
|
||||||
|
${PYTHON_INCLUDE_PATH}
|
||||||
|
${Boost_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
set ( includes vlsisapd/liberty/Attribute.h
|
||||||
|
vlsisapd/liberty/Cell.h
|
||||||
|
vlsisapd/liberty/FlipFlop.h
|
||||||
|
vlsisapd/liberty/Library.h
|
||||||
|
vlsisapd/liberty/Name.h
|
||||||
|
vlsisapd/liberty/Pin.h
|
||||||
|
vlsisapd/liberty/Timing.h
|
||||||
|
vlsisapd/liberty/WireLoad.h
|
||||||
|
vlsisapd/liberty/WireLoadArea.h
|
||||||
|
vlsisapd/liberty/WireLoadSelection.h
|
||||||
|
)
|
||||||
|
set ( cpps Attribute.cpp
|
||||||
|
Cell.cpp
|
||||||
|
FlipFlop.cpp
|
||||||
|
Library.cpp
|
||||||
|
Name.cpp
|
||||||
|
Pin.cpp
|
||||||
|
Timing.cpp
|
||||||
|
WireLoad.cpp
|
||||||
|
WireLoadArea.cpp
|
||||||
|
WireLoadSelection.cpp
|
||||||
|
)
|
||||||
|
set ( LibertyParserScanner ${VLSISAPD_SOURCE_DIR}/src/liberty/src/LibertyParserScanner.ll )
|
||||||
|
set ( LibertyParserGrammar ${VLSISAPD_SOURCE_DIR}/src/liberty/src/LibertyParserGrammar.yy )
|
||||||
|
set ( LibertyParserScannerCpp LibertyParserScanner.cpp )
|
||||||
|
set ( LibertyParserGrammarCpp LibertyParserGrammar.cpp )
|
||||||
|
add_custom_target ( LibertyParser echo "Creating Liberty parser" )
|
||||||
|
add_custom_command ( SOURCE ${LibertyParserScanner}
|
||||||
|
COMMAND ${FLEX_EXECUTABLE}
|
||||||
|
ARGS -PLiberty_ -o${LibertyParserScannerCpp} ${LibertyParserScanner}
|
||||||
|
TARGET LibertyParser
|
||||||
|
OUTPUTS ${LibertyParserScannerCpp}
|
||||||
|
)
|
||||||
|
add_custom_command ( SOURCE ${LibertyParserGrammar}
|
||||||
|
COMMAND ${BISON_EXECUTABLE}
|
||||||
|
ARGS -d -v -p Liberty_ -y ${LibertyParserGrammar} -o ${LibertyParserGrammarCpp}
|
||||||
|
TARGET LibertyParser
|
||||||
|
DEPENDS ${LibertyParserScannerCpp}
|
||||||
|
OUTPUTS ${LibertyParserGrammarCpp}
|
||||||
|
)
|
||||||
|
set ( liberty_parser_cpps ${LibertyParserScannerCpp}
|
||||||
|
${LibertyParserGrammarCpp}
|
||||||
|
)
|
||||||
|
set_source_files_properties ( ${LibertyParserScannerCpp} GENERATED )
|
||||||
|
set_source_files_properties ( ${LibertyParserGrammarCpp} GENERATED )
|
||||||
|
|
||||||
|
|
||||||
|
add_library ( liberty ${cpps}
|
||||||
|
${liberty_parser_cpps}
|
||||||
|
)
|
||||||
|
target_link_libraries ( liberty ${HURRICANE_PYTHON_LIBRARIES}
|
||||||
|
${Boost_LIBRARIES}
|
||||||
|
${PYTHON_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
install ( TARGETS liberty DESTINATION lib${LIB_SUFFIX} )
|
||||||
|
install ( FILES ${includes} DESTINATION include/vlsisapd/liberty )
|
|
@ -0,0 +1,103 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Cell.h"
|
||||||
|
#include "vlsisapd/liberty/Pin.h"
|
||||||
|
#include "vlsisapd/liberty/FlipFlop.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
Cell::Cell(Name name): _name(name), _attributes(), _pins(), _ff(NULL), _test_cell(NULL) {};
|
||||||
|
|
||||||
|
Pin* Cell::getPin(Name pinName) {
|
||||||
|
Pin* pin = NULL;
|
||||||
|
map<Name, Pin*>::iterator it = _pins.find(pinName);
|
||||||
|
if (it == _pins.end()) {
|
||||||
|
cerr << "[ERROR] Cell " << _name.getString() << " has no pin named " << pinName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
pin= (*it).second;
|
||||||
|
return pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cell::addAttribute(Name attrName, Attribute::Type attrType, string& attrValue) {
|
||||||
|
Attribute* attr = new Attribute(attrName, attrType, attrValue);
|
||||||
|
map<Name, Attribute*>::iterator it = _attributes.find(attrName);
|
||||||
|
if (it != _attributes.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define two Cells's attributes with the same name: " << attrName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_attributes[attrName] = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cell::addPin(Name pinName) {
|
||||||
|
Pin* pin = new Pin(pinName);
|
||||||
|
map<Name, Pin*>::iterator it = _pins.find(pinName);
|
||||||
|
if (it != _pins.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define two Cells's pins with the same name: " << _name.getString() << " -> " << pinName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_pins[pinName] = pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cell::addFF(Name noninverting, Name inverting) {
|
||||||
|
FlipFlop* flipflop = new FlipFlop(noninverting, inverting);
|
||||||
|
_ff = flipflop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cell::setTestCell(Cell *cell) {
|
||||||
|
_test_cell = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cell::print() {
|
||||||
|
cout << "| Cell name= " << _name.getString() << endl;
|
||||||
|
|
||||||
|
// Cell's attributes
|
||||||
|
cout << "| Attributes :" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
cout << "| name= " << (*it).first.getString()
|
||||||
|
<< ", type= " << (*it).second->typeToString((*it).second->getType())
|
||||||
|
<< ", value= " << (*it).second->valueAsString() << endl;
|
||||||
|
}
|
||||||
|
// Cell's pins
|
||||||
|
for(map<Name, Pin*>::const_iterator it=_pins.begin() ; it!=_pins.end() ; ++it) {
|
||||||
|
(*it).second->print();
|
||||||
|
}
|
||||||
|
// FF
|
||||||
|
if(_ff)
|
||||||
|
_ff->print();
|
||||||
|
// test_cell
|
||||||
|
if(_test_cell)
|
||||||
|
_test_cell->print();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cell::write(ofstream &file, bool test) {
|
||||||
|
if(_name.getString()=="test_cell") {
|
||||||
|
if(test==false)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
file << " test_cell () {" << endl;
|
||||||
|
} else {
|
||||||
|
file << " cell (" << _name.getString() << ") {" << endl;
|
||||||
|
}
|
||||||
|
// Cell's attributes
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
file << " ";
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
// Cell's pin
|
||||||
|
for(map<Name, Pin*>::const_iterator it=_pins.begin() ; it!=_pins.end() ; ++it) {
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
// FF
|
||||||
|
if(_ff)
|
||||||
|
_ff->write(file);
|
||||||
|
// test_cell
|
||||||
|
if(_test_cell)
|
||||||
|
_test_cell->write(file, true);
|
||||||
|
file << " }" << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/FlipFlop.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
FlipFlop::FlipFlop(Name noninverting, Name inverting): _noninverting(noninverting), _inverting(inverting), _attributes() {};
|
||||||
|
|
||||||
|
void FlipFlop::addAttribute(Name attrName, Attribute::Type attrType, string& attrValue) {
|
||||||
|
Attribute* attr = new Attribute(attrName, attrType, attrValue);
|
||||||
|
map<Name, Attribute*>::iterator it = _attributes.find(attrName);
|
||||||
|
if (it != _attributes.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define FlipFlop with several attributes with the same name: " << attrName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_attributes[attrName] = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlipFlop::print() {
|
||||||
|
cout << "| FF noninverting= " << _noninverting.getString() << ", inverting= " << _inverting.getString() << endl;
|
||||||
|
|
||||||
|
// FlipFlop's attributes
|
||||||
|
cout << "| Attributes :" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
cout << "| name= " << (*it).first.getString()
|
||||||
|
<< ", type= " << (*it).second->typeToString((*it).second->getType())
|
||||||
|
<< ", value= " << (*it).second->valueAsString() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FlipFlop::write(ofstream &file) {
|
||||||
|
file << " ff(\"" << _noninverting.getString() << "\",\"" << _inverting.getString() << "\") {" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
file << " ";
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
file << " }" << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -0,0 +1,489 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
using namespace std;
|
||||||
|
#include<vector>
|
||||||
|
#include<boost/regex.hpp>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Library.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Timing.h"
|
||||||
|
using namespace LIB;
|
||||||
|
|
||||||
|
int Liberty_error ( const char* message );
|
||||||
|
extern int Liberty_lex ();
|
||||||
|
extern FILE* Liberty_in;
|
||||||
|
extern int Liberty_lineno;
|
||||||
|
|
||||||
|
static Library* library = NULL;
|
||||||
|
Name currentWireLoad = "";
|
||||||
|
Name currentCell = "";
|
||||||
|
vector<Name> listPins;
|
||||||
|
static Timing* currentTiming = NULL;
|
||||||
|
|
||||||
|
string intToString(int d) {
|
||||||
|
ostringstream oss;
|
||||||
|
oss << d;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string doubleToString(double d) {
|
||||||
|
ostringstream oss;
|
||||||
|
oss << d;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
double _value;
|
||||||
|
const char* _text;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token LIBRARY
|
||||||
|
%token DATE REVISION
|
||||||
|
%token DEFAULT_INOUT_PIN_CAP DEFAULT_INOUT_PIN_FALL_RES DEFAULT_INOUT_PIN_RISE_RES DEFAULT_INPUT_PIN_CAP DEFAULT_INTRINSIC_FALL DEFAULT_INTRINSIC_RISE DEFAULT_OUTPUT_PIN_CAP DEFAULT_OUTPUT_PIN_FALL_RES DEFAULT_OUTPUT_PIN_RISE_RES DEFAULT_SLOPE_FALL DEFAULT_SLOPE_RISE DEFAULT_FANOUT_LOAD DEFAULT_MAX_FANOUT DEFAULT_WIRE_LOAD_CAPACITANCE DEFAULT_WIRE_LOAD_RESISTANCE DEFAULT_WIRE_LOAD_AREA DEFAULT_WIRE_LOAD_MODE
|
||||||
|
%token K_PROCESS_DRIVE_FALL K_PROCESS_DRIVE_RISE K_PROCESS_INTRINSIC_FALL K_PROCESS_INTRINSIC_RISE K_PROCESS_PIN_CAP K_PROCESS_SLOPE_FALL K_PROCESS_SLOPE_RISE K_PROCESS_WIRE_CAP K_PROCESS_WIRE_RES K_TEMP_DRIVE_FALL K_TEMP_DRIVE_RISE K_TEMP_INTRINSIC_FALL K_TEMP_INTRINSIC_RISE K_TEMP_PIN_CAP K_TEMP_SLOPE_FALL K_TEMP_SLOPE_RISE K_TEMP_WIRE_CAP K_TEMP_WIRE_RES K_VOLT_DRIVE_FALL K_VOLT_DRIVE_RISE K_VOLT_INTRINSIC_FALL K_VOLT_INTRINSIC_RISE K_VOLT_PIN_CAP K_VOLT_SLOPE_FALL K_VOLT_SLOPE_RISE K_VOLT_WIRE_CAP K_VOLT_WIRE_RES
|
||||||
|
%token TIME_UNIT VOLTAGE_UNIT CURRENT_UNIT PULLING_RESISTANCE_UNIT CAPACITIVE_LOAD_UNIT
|
||||||
|
%token NOM_PROCESS NOM_TEMPERATURE NOM_VOLTAGE IN_PLACE_SWAP_MODE
|
||||||
|
|
||||||
|
// wire_load
|
||||||
|
%token WIRE_LOAD
|
||||||
|
%token RESISTANCE CAPACITANCE AREA SLOPE FANOUT_LENGTH
|
||||||
|
%token WIRE_LOAD_SELECTION WIRE_LOAD_FROM_AREA
|
||||||
|
%token DEFAULT_WIRE_LOAD_SELECTION
|
||||||
|
|
||||||
|
// cell
|
||||||
|
%token CELL
|
||||||
|
%token CELL_FOOTPRINT DONT_USE // AREA already done
|
||||||
|
// cell::pin
|
||||||
|
%token PIN
|
||||||
|
%token DIRECTION
|
||||||
|
%token FANOUT_LOAD // CAPACITANCE already done
|
||||||
|
%token MAX_FANOUT FUNCTION THREE_STATE
|
||||||
|
%token DRIVER_TYPE
|
||||||
|
// cell::pin::timing
|
||||||
|
%token TIMING
|
||||||
|
%token TIMING_SENSE TIMING_TYPE INTRINSIC_RISE INTRINSIC_FALL RISE_RESISTANCE FALL_RESISTANCE RELATED_PIN
|
||||||
|
// cell::ff
|
||||||
|
%token FF NEXT_STATE CLOCKED_ON
|
||||||
|
// text_cell
|
||||||
|
%token TEST_CELL SIGNAL_TYPE
|
||||||
|
|
||||||
|
// values
|
||||||
|
%token INTEGER FLOAT
|
||||||
|
%token STRING_NAME STRING_DATE STRING_UNIT STRING_FUNCTION STRING_FF
|
||||||
|
|
||||||
|
%type<_value> INTEGER FLOAT
|
||||||
|
%type<_text> STRING_NAME STRING_DATE STRING_UNIT STRING_FUNCTION STRING_FF
|
||||||
|
|
||||||
|
%debug
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
file
|
||||||
|
: library_header '{' library_content '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
library_header
|
||||||
|
: LIBRARY '(' STRING_NAME ')' { library = new Library ( Name($3) ); }
|
||||||
|
;
|
||||||
|
|
||||||
|
library_content
|
||||||
|
: // empty
|
||||||
|
| library_item library_content
|
||||||
|
;
|
||||||
|
|
||||||
|
library_item
|
||||||
|
: DATE ':' '"' STRING_DATE '"' ';' { /*cerr << " ° Date is : " << $4 << endl;*/ }
|
||||||
|
| REVISION ':' FLOAT ';' { /*cerr << " ° Revision is : " << $3 << endl;*/ }
|
||||||
|
| library_default
|
||||||
|
| library_wire_load
|
||||||
|
| library_wire_load_selection
|
||||||
|
| library_cell
|
||||||
|
;
|
||||||
|
|
||||||
|
library_default
|
||||||
|
: DEFAULT_INOUT_PIN_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_inout_pin_cap"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_INOUT_PIN_FALL_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_inout_pin_fall_res"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_INOUT_PIN_RISE_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_inout_pin_rise_res"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_INPUT_PIN_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_input_pin_cap"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_INTRINSIC_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_intrinsic_fall"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_INTRINSIC_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_intrinsic_rise"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_OUTPUT_PIN_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_output_pin_cap"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_OUTPUT_PIN_FALL_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_output_pin_fall_res"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_OUTPUT_PIN_RISE_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_output_pin_rise_res"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_SLOPE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_slope_fall"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_SLOPE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_slope_rise"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_FANOUT_LOAD ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_fanout_load"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_MAX_FANOUT ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_max_fanout"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_WIRE_LOAD_CAPACITANCE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_wire_load_capacitance"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_WIRE_LOAD_RESISTANCE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_wire_load_resistance"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_WIRE_LOAD_AREA ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("default_wire_load_area"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_DRIVE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_drive_fall"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_DRIVE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_drive_rise"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_INTRINSIC_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_intrinsic_fall"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_INTRINSIC_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_intrinsic_rise"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_PIN_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_pin_cap"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_SLOPE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_slope_fall"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_SLOPE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_slope_rise"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_WIRE_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_wire_cap"), Attribute::Double, value); }
|
||||||
|
| K_PROCESS_WIRE_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_process_wire_res"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_DRIVE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_drive_fall"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_DRIVE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_drive_rise"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_INTRINSIC_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_intrinsic_fall"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_INTRINSIC_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_intrinsic_rise"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_PIN_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_pin_cap"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_SLOPE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_slope_fall"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_SLOPE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_slope_rise"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_WIRE_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_wire_cap"), Attribute::Double, value); }
|
||||||
|
| K_TEMP_WIRE_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_temp_wire_res"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_DRIVE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_drive_fall"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_DRIVE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_drive_rise"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_INTRINSIC_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_intrinsic_fall"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_INTRINSIC_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_intrinsic_rise"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_PIN_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_pin_cap"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_SLOPE_FALL ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_slop_fall"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_SLOPE_RISE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_slop_rise"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_WIRE_CAP ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_wire_cap"), Attribute::Double, value); }
|
||||||
|
| K_VOLT_WIRE_RES ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("k_volt_wire_res"), Attribute::Double, value); }
|
||||||
|
| NOM_PROCESS ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("nom_process"), Attribute::Double, value); }
|
||||||
|
| NOM_TEMPERATURE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("nom_temperature"), Attribute::Double, value); }
|
||||||
|
| NOM_VOLTAGE ':' FLOAT ';' { string value=doubleToString($3); library->addAttribute(Name("nom_voltage"), Attribute::Double, value); }
|
||||||
|
| DEFAULT_WIRE_LOAD_SELECTION ':' STRING_NAME { string value=$3; library->addAttribute(Name("default_wire_load_selection"), Attribute::String, value); }
|
||||||
|
| DEFAULT_WIRE_LOAD_MODE ':' STRING_NAME ';' {
|
||||||
|
string value=$3;
|
||||||
|
if ( (value != "top") & (value != "segmented") & (value != "enclosed") ) {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for default_wire_load_mode parameter. Valid values are top, segmented and enclosed." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->addAttribute(Name("default_wire_load_mode"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| TIME_UNIT ':' '"' STRING_UNIT '"' ';' {
|
||||||
|
string chaine=$4;
|
||||||
|
boost::regex expression("([0-1]+)([pn]s)");
|
||||||
|
boost::cmatch match;
|
||||||
|
string value, unit;
|
||||||
|
if(boost::regex_match(chaine.c_str(), match, expression)) {
|
||||||
|
value=match[1];
|
||||||
|
unit=match[2];
|
||||||
|
} else {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for time_unit parameter. Valid values are 1ps, 10ps, 100ps, and 1ns." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->addAttribute(Name("time_unit"), Attribute::Unit, value, unit);
|
||||||
|
}
|
||||||
|
| VOLTAGE_UNIT ':' '"' STRING_UNIT '"' ';' {
|
||||||
|
string chaine=$4;
|
||||||
|
boost::regex expression("([0-1]+)([m]?V)");
|
||||||
|
boost::cmatch match;
|
||||||
|
string value, unit;
|
||||||
|
if(boost::regex_match(chaine.c_str(), match, expression)) {
|
||||||
|
value=match[1];
|
||||||
|
unit=match[2];
|
||||||
|
} else {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for voltage_unit parameter. Valid values are 1mV, 10mV, 100mV, and 1V." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->addAttribute(Name("voltage_unit"), Attribute::Unit, value, unit);
|
||||||
|
}
|
||||||
|
| CURRENT_UNIT ':' '"' STRING_UNIT '"' ';' {
|
||||||
|
string chaine=$4;
|
||||||
|
boost::regex expression("([0-1]+)([um]?A)");
|
||||||
|
boost::cmatch match;
|
||||||
|
string value, unit;
|
||||||
|
if(boost::regex_match(chaine.c_str(), match, expression)) {
|
||||||
|
value=match[1];
|
||||||
|
unit=match[2];
|
||||||
|
} else {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for current_unit parameter. Valid values are 1uA, 10uA, 100uA, 1mA, 10mA, 100mA, and 1A." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->addAttribute(Name("current_unit"), Attribute::Unit, value, unit);
|
||||||
|
}
|
||||||
|
| PULLING_RESISTANCE_UNIT ':' '"' STRING_UNIT '"' ';' {
|
||||||
|
string chaine=$4;
|
||||||
|
boost::regex expression("([0-1]+)([k]?ohm)");
|
||||||
|
boost::cmatch match;
|
||||||
|
string value, unit;
|
||||||
|
if(boost::regex_match(chaine.c_str(), match, expression)) {
|
||||||
|
value=match[1];
|
||||||
|
unit=match[2];
|
||||||
|
} else {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for pulling_resistance_unit parameter. Valid values are 1ohm, 10ohm, 100ohm, and 1kohm." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->addAttribute(Name("pulling_resistance_unit"), Attribute::Unit, value, unit);
|
||||||
|
}
|
||||||
|
| IN_PLACE_SWAP_MODE ':' STRING_NAME ';' {
|
||||||
|
string value=$3;
|
||||||
|
if ( (value != "match_footprint") & (value != "no_swapping") ) {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for pulling_resistance_unit parameter. Valid values are match_footprint and no_swapping." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->addAttribute(Name("in_place_swap_mode"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| CAPACITIVE_LOAD_UNIT '(' FLOAT ',' STRING_NAME ')' ';' { string value=doubleToString($3), unit=$5; library->addAttribute(Name("capacitive_load_unit"), Attribute::Unit, value, unit); }
|
||||||
|
;
|
||||||
|
|
||||||
|
library_wire_load
|
||||||
|
: wire_header '{' wire_content '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
wire_header
|
||||||
|
: WIRE_LOAD '(' '"' STRING_NAME '"' ')' { currentWireLoad=Name($4); library->addWireLoad(currentWireLoad); }
|
||||||
|
;
|
||||||
|
|
||||||
|
wire_content
|
||||||
|
: // empty
|
||||||
|
| wire_item wire_content
|
||||||
|
;
|
||||||
|
|
||||||
|
wire_item
|
||||||
|
: RESISTANCE ':' FLOAT ';' { string value=doubleToString($3); library->getWireLoad(currentWireLoad)->addAttribute(Name("resistance"), Attribute::Double, value); }
|
||||||
|
| CAPACITANCE ':' FLOAT ';' { string value=doubleToString($3); library->getWireLoad(currentWireLoad)->addAttribute(Name("capacitance"), Attribute::Double, value); }
|
||||||
|
| AREA ':' FLOAT ';' { string value=doubleToString($3); library->getWireLoad(currentWireLoad)->addAttribute(Name("area"), Attribute::Double, value); }
|
||||||
|
| SLOPE ':' FLOAT ';' { string value=doubleToString($3); library->getWireLoad(currentWireLoad)->addAttribute(Name("slope"), Attribute::Double, value); }
|
||||||
|
| FANOUT_LENGTH '(' FLOAT ',' FLOAT ')' ';' { string value1=doubleToString($3), value2=doubleToString($5); library->getWireLoad(currentWireLoad)->addAttribute(Name("fanout_length"), Attribute::Pair, value1, value2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
library_wire_load_selection
|
||||||
|
: wire_selection_header '{' wire_selection_content '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
wire_selection_header
|
||||||
|
: WIRE_LOAD_SELECTION '(' STRING_NAME ')' { library->addWireLoadSelection(Name($3)); }
|
||||||
|
;
|
||||||
|
|
||||||
|
wire_selection_content
|
||||||
|
: // empty
|
||||||
|
| wire_selection_item wire_selection_content
|
||||||
|
;
|
||||||
|
|
||||||
|
wire_selection_item
|
||||||
|
: WIRE_LOAD_FROM_AREA '(' FLOAT ',' FLOAT ',' '"' STRING_NAME '"' ')' ';'
|
||||||
|
{
|
||||||
|
double value1=$3, value2=$5;
|
||||||
|
string name=$8;
|
||||||
|
library->getWireLoadSelection()->addWireLoadArea(value1, value2, Name(name));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
library_cell
|
||||||
|
: cell_header '{' cell_content '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
cell_header
|
||||||
|
: CELL '(' STRING_NAME ')' { currentCell = Name($3); library->addCell(currentCell); }
|
||||||
|
;
|
||||||
|
|
||||||
|
cell_content
|
||||||
|
: // empty
|
||||||
|
| cell_item cell_content
|
||||||
|
;
|
||||||
|
|
||||||
|
cell_item
|
||||||
|
: AREA ':' FLOAT { /* TODO ; a la fin optionnel ? pour tous en fait ... */string value=doubleToString($3); library->getCell(currentCell)->addAttribute(Name("area"), Attribute::Double, value); }
|
||||||
|
| CELL_FOOTPRINT ':' '"' STRING_NAME '"' ';' { string value=$4; library->getCell(currentCell)->addAttribute(Name("cell_footprint"), Attribute::String, value); }
|
||||||
|
| DONT_USE ':' STRING_NAME ';' { string value=$3; library->getCell(currentCell)->addAttribute(Name("dont_use"), Attribute::String, value); }
|
||||||
|
| test_cell_header '{' cell_content '}'
|
||||||
|
| pin_header '{' pin_content '}' { listPins.clear(); }
|
||||||
|
| ff_header '{' ff_content '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
test_cell_header
|
||||||
|
: TEST_CELL '(' ')'
|
||||||
|
{
|
||||||
|
Name oldCell = currentCell;
|
||||||
|
currentCell = Name("test_cell");
|
||||||
|
library->addCell(currentCell);
|
||||||
|
library->getCell(oldCell)->setTestCell(library->getCell(currentCell));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
pin_header
|
||||||
|
: PIN '(' pin_list ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
pin_list
|
||||||
|
: STRING_NAME { listPins.push_back(Name($1)); library->getCell(currentCell)->addPin(Name($1)); }
|
||||||
|
| pin_list ',' STRING_NAME { listPins.push_back(Name($3)); library->getCell(currentCell)->addPin(Name($3)); }
|
||||||
|
;
|
||||||
|
|
||||||
|
pin_content
|
||||||
|
: // empty
|
||||||
|
| pin_item pin_content
|
||||||
|
;
|
||||||
|
|
||||||
|
pin_item
|
||||||
|
: CAPACITANCE ':' FLOAT ';'
|
||||||
|
{
|
||||||
|
string value=doubleToString($3);
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("capacitance"), Attribute::Double, value);
|
||||||
|
}
|
||||||
|
| FANOUT_LOAD ':' FLOAT ';'
|
||||||
|
{
|
||||||
|
string value=doubleToString($3);
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("fanout_load"), Attribute::Double, value);
|
||||||
|
}
|
||||||
|
| MAX_FANOUT ':' FLOAT ';'
|
||||||
|
{
|
||||||
|
string value=doubleToString($3);
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("max_fanout"), Attribute::Double, value);
|
||||||
|
}
|
||||||
|
| THREE_STATE ':' '"' STRING_FUNCTION '"' ';'
|
||||||
|
{
|
||||||
|
string value=$4;
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("three_state"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| DRIVER_TYPE ':' STRING_NAME ';'
|
||||||
|
{
|
||||||
|
string value=$3;
|
||||||
|
if ( (value != "pull_up") & (value != "pull_down") ) {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for driver_type parameter. Valid values are pull_up and pull_down." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("driver_type"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| FUNCTION ':' '"' STRING_FUNCTION '"' ';'
|
||||||
|
{
|
||||||
|
string value=$4;
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("function"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| FUNCTION ':' '"' STRING_NAME '"' ';'
|
||||||
|
{
|
||||||
|
/* STRING_NAME matched in case of a buffer */
|
||||||
|
string value=$4;
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("function"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| FUNCTION ':' '"' FLOAT '"' ';'
|
||||||
|
{
|
||||||
|
/* FLOAT matched in case of one and zero */
|
||||||
|
string value=doubleToString($4);
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("function"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| DIRECTION ':' STRING_NAME ';'
|
||||||
|
{
|
||||||
|
string value=$3;
|
||||||
|
if ( (value != "input") & (value != "output") ) {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for direction parameter. Valid values are input and output." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("direction"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| SIGNAL_TYPE ':' STRING_NAME ';' {
|
||||||
|
string value=$3;
|
||||||
|
if ( (value != "test_scan_in") & (value != "test_scan_in_inverted") & (value != "test_scan_out") & (value != "test_scan_out_inverted") & (value != "test_scan_enable") & (value != "test_scan_enable_inverted") & (value != "test_scan_clock") & (value != "test_scan_clock_a") & (value != "test_scan_clock_b") & (value != "test_clock") ) {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid value for signal_type parameter. Valid values are test_scan_in, test_scan_in_inverted, test_scan_out, test_scan_out_inverted, test_scan_enable, test_scan_enable_inverted, test_scan_clock, test_scan_clock_a, test_scan_clock_b and test_clock." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
Cell* cell = library->getCell(currentCell);
|
||||||
|
for (size_t i = 0 ; i < listPins.size() ; i++)
|
||||||
|
cell->getPin(listPins[i])->addAttribute(Name("signal_type"), Attribute::String, value);
|
||||||
|
}
|
||||||
|
| timing_header '{' timing_content '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
timing_header
|
||||||
|
: TIMING '(' ')'
|
||||||
|
{
|
||||||
|
library->getCell(currentCell)->getPin(listPins.back())->addTiming();
|
||||||
|
currentTiming=library->getCell(currentCell)->getPin(listPins.back())->getTiming().back();
|
||||||
|
// only for 1 pin, not available for pins' list
|
||||||
|
if(listPins.size()>1)
|
||||||
|
cerr << "[Warning] timing information for a list of pins, not available." << endl;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
timing_content
|
||||||
|
: // empty
|
||||||
|
| timing_item timing_content
|
||||||
|
;
|
||||||
|
|
||||||
|
timing_item
|
||||||
|
: INTRINSIC_RISE ':' FLOAT ';' { string value=doubleToString($3); currentTiming->addAttribute(Name("intrinsic_rise"), Attribute::Double, value); }
|
||||||
|
| INTRINSIC_FALL ':' FLOAT ';' { string value=doubleToString($3); currentTiming->addAttribute(Name("intrinsic_fall"), Attribute::Double, value); }
|
||||||
|
| RISE_RESISTANCE ':' FLOAT ';' { string value=doubleToString($3); currentTiming->addAttribute(Name("rise_resistance"), Attribute::Double, value); }
|
||||||
|
| FALL_RESISTANCE ':' FLOAT ';' { string value=doubleToString($3); currentTiming->addAttribute(Name("fall_resistance"), Attribute::Double, value); }
|
||||||
|
| TIMING_SENSE ':' STRING_NAME ';' { string value=$3; currentTiming->addAttribute(Name("timing_sense"), Attribute::String, value); }
|
||||||
|
| TIMING_TYPE ':' STRING_NAME ';' { string value=$3; currentTiming->addAttribute(Name("timing_type"), Attribute::String, value); }
|
||||||
|
| RELATED_PIN ':' '"' STRING_NAME '"' ';' { string value=$4; currentTiming->addAttribute(Name("related_pin"), Attribute::String, value); }
|
||||||
|
;
|
||||||
|
|
||||||
|
ff_header
|
||||||
|
: FF '(' STRING_FF ')'
|
||||||
|
{
|
||||||
|
string chaine=$3;
|
||||||
|
boost::regex expression("\"?([A-Z]+)\"?,\"?([A-Z]+)\"?");
|
||||||
|
boost::cmatch match;
|
||||||
|
string value1, value2;
|
||||||
|
if(boost::regex_match(chaine.c_str(), match, expression)) {
|
||||||
|
value1=match[1];
|
||||||
|
value2=match[2];
|
||||||
|
} else {
|
||||||
|
cerr << "[Liberty PARSE ERROR] Invalid syntax for ff group." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
library->getCell(currentCell)->addFF(Name(value1), Name(value2));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
ff_content
|
||||||
|
: // empty
|
||||||
|
| ff_item ff_content
|
||||||
|
;
|
||||||
|
|
||||||
|
ff_item
|
||||||
|
: NEXT_STATE ':' '"' STRING_FUNCTION '"' ';' { string value=$4; library->getCell(currentCell)->getFF()->addAttribute(Name("next_state"), Attribute::String, value); }
|
||||||
|
| NEXT_STATE ':' '"' STRING_NAME '"' ';' { string value=$4; library->getCell(currentCell)->getFF()->addAttribute(Name("next_state"), Attribute::String, value); /* STRING_NAME matched in case of a buffer */ }
|
||||||
|
| CLOCKED_ON ':' '"' STRING_NAME '"' ';' { string value=$4; library->getCell(currentCell)->getFF()->addAttribute(Name("clocked_on"), Attribute::String, value); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int Liberty_error ( const char* message )
|
||||||
|
// ***************************************
|
||||||
|
{
|
||||||
|
cerr << endl << "libertyParser(): " << message << " at line " << Liberty_lineno << endl << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void read ( std::string fileName )
|
||||||
|
// *******************************
|
||||||
|
{
|
||||||
|
const char* fileC = fileName.c_str ();
|
||||||
|
Liberty_in = fopen ( fileC, "r" );
|
||||||
|
if ( !Liberty_in ) {
|
||||||
|
cerr << "libertyParser(): no file found with the name " << fileC << ".";
|
||||||
|
}
|
||||||
|
yyparse ();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace LIB{
|
||||||
|
Library* Library::readFromFile ( std::string fileName )
|
||||||
|
// ****************************************************
|
||||||
|
{
|
||||||
|
read ( fileName );
|
||||||
|
return library;
|
||||||
|
}
|
||||||
|
} // namespace
|
|
@ -0,0 +1,175 @@
|
||||||
|
|
||||||
|
%{
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "LibertyParserGrammar.hpp"
|
||||||
|
|
||||||
|
static double floatToken;
|
||||||
|
static std::string nameToken;
|
||||||
|
|
||||||
|
extern int yylineno;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%x COMM
|
||||||
|
|
||||||
|
SPACE [ \t]
|
||||||
|
UPPER_CASE_LETTER [A-Z]
|
||||||
|
LOWER_CASE_LETTER [a-z]
|
||||||
|
DIGIT [0-9]
|
||||||
|
OPERATION [\*\+\^]
|
||||||
|
|
||||||
|
INTEGER {DIGIT}+
|
||||||
|
FLOAT {DIGIT}+(\.{DIGIT}+)*
|
||||||
|
LETTER {UPPER_CASE_LETTER}|{LOWER_CASE_LETTER}
|
||||||
|
ALPHA_NUM {LETTER}+{DIGIT}*
|
||||||
|
|
||||||
|
STRING_NAME {ALPHA_NUM}+(_{ALPHA_NUM})*
|
||||||
|
|
||||||
|
HOUR {DIGIT}+:{DIGIT}+:{DIGIT}+
|
||||||
|
STRING_DATE {LETTER}+{SPACE}+{LETTER}+{SPACE}+{DIGIT}+{SPACE}+{HOUR}{SPACE}+MET{SPACE}+{DIGIT}+
|
||||||
|
|
||||||
|
STRING_UNIT {DIGIT}+{LETTER}+
|
||||||
|
|
||||||
|
OPERATION_SPACED {SPACE}*{OPERATION}{SPACE}*
|
||||||
|
FUNCTION1 {ALPHA_NUM}'?
|
||||||
|
FUNCTION2 (\()?{FUNCTION1}{OPERATION_SPACED}{FUNCTION1}(\))?
|
||||||
|
FUNCTION3_1 (\()?{FUNCTION1}{OPERATION_SPACED}{FUNCTION1}{OPERATION_SPACED}*{FUNCTION1}(\))?
|
||||||
|
FUNCTION3_2 (\()?{FUNCTION2}{OPERATION_SPACED}{FUNCTION1}(\))?
|
||||||
|
FUNCTION3_3 (\()?{FUNCTION1}{OPERATION_SPACED}{FUNCTION2}(\))?
|
||||||
|
FUNCTION3 {FUNCTION3_1}|{FUNCTION3_2}|{FUNCTION3_3}
|
||||||
|
FUNCTION4_1 (\()?{FUNCTION1}{OPERATION_SPACED}{FUNCTION3}(\))?
|
||||||
|
FUNCTION4_2 (\()?{FUNCTION2}{OPERATION_SPACED}{FUNCTION2}(\))?
|
||||||
|
FUNCTION4_3 (\()?(\()?{FUNCTION2}{OPERATION_SPACED}{FUNCTION1}(\))?{OPERATION_SPACED}{FUNCTION1}(\))?
|
||||||
|
FUNCTION4 {FUNCTION4_1}|{FUNCTION4_2}|{FUNCTION4_3}
|
||||||
|
FUNCTION5 (\()?{FUNCTION2}{OPERATION_SPACED}{FUNCTION3}(\))?
|
||||||
|
FUNCTION6 (\()?{FUNCTION2}{OPERATION_SPACED}{FUNCTION2}(\))?{OPERATION_SPACED}{FUNCTION2}(\))?
|
||||||
|
FUNCTION7 (\()?{FUNCTION3}{OPERATION_SPACED}{FUNCTION4}(\))?
|
||||||
|
FUNCTION8 (\()?{FUNCTION4}{OPERATION_SPACED}{FUNCTION4}(\))?
|
||||||
|
FUNCTION_MUX3 (\()?{FUNCTION2}{OPERATION_SPACED}(\()?{FUNCTION1}{OPERATION_SPACED}{FUNCTION4}(\))?(\))?
|
||||||
|
FUNCTION_MUX {FUNCTION_MUX3}
|
||||||
|
STRING_FUNCTION {FUNCTION1}|{FUNCTION2}|{FUNCTION3}|{FUNCTION4}|{FUNCTION5}|{FUNCTION6}|{FUNCTION7}|{FUNCTION8}|{FUNCTION_MUX}
|
||||||
|
|
||||||
|
STRING_FF [\"]?{UPPER_CASE_LETTER}+[\"]?,[\"]?{UPPER_CASE_LETTER}+[\"]?
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
{SPACE} { /* spaces : skip them */ }
|
||||||
|
\n { yylineno++; /* end of line */ }
|
||||||
|
|
||||||
|
<INITIAL>[ \t]+
|
||||||
|
<INITIAL>"/*" { BEGIN(COMM); }
|
||||||
|
<COMM>.
|
||||||
|
<COMM>"*/" { BEGIN(INITIAL); }
|
||||||
|
<INITIAL,COMM>\n { yylineno++; }
|
||||||
|
<INITIAL,COMM>\\\n { yylineno++; }
|
||||||
|
|
||||||
|
library { return LIBRARY; }
|
||||||
|
|
||||||
|
date { return DATE; }
|
||||||
|
revision { return REVISION; }
|
||||||
|
|
||||||
|
default_inout_pin_cap { return DEFAULT_INOUT_PIN_CAP; }
|
||||||
|
default_inout_pin_fall_res { return DEFAULT_INOUT_PIN_FALL_RES; }
|
||||||
|
default_inout_pin_rise_res { return DEFAULT_INOUT_PIN_RISE_RES; }
|
||||||
|
default_input_pin_cap { return DEFAULT_INPUT_PIN_CAP; }
|
||||||
|
default_intrinsic_fall { return DEFAULT_INTRINSIC_FALL; }
|
||||||
|
default_intrinsic_rise { return DEFAULT_INTRINSIC_RISE; }
|
||||||
|
default_output_pin_cap { return DEFAULT_OUTPUT_PIN_CAP; }
|
||||||
|
default_output_pin_fall_res { return DEFAULT_OUTPUT_PIN_FALL_RES; }
|
||||||
|
default_output_pin_rise_res { return DEFAULT_OUTPUT_PIN_RISE_RES; }
|
||||||
|
default_slope_fall { return DEFAULT_SLOPE_FALL; }
|
||||||
|
default_slope_rise { return DEFAULT_SLOPE_RISE; }
|
||||||
|
default_fanout_load { return DEFAULT_FANOUT_LOAD; }
|
||||||
|
default_max_fanout { return DEFAULT_MAX_FANOUT; }
|
||||||
|
default_wire_load_capacitance { return DEFAULT_WIRE_LOAD_CAPACITANCE; }
|
||||||
|
default_wire_load_resistance { return DEFAULT_WIRE_LOAD_RESISTANCE; }
|
||||||
|
default_wire_load_area { return DEFAULT_WIRE_LOAD_AREA; }
|
||||||
|
default_wire_load_mode { return DEFAULT_WIRE_LOAD_MODE; }
|
||||||
|
k_process_drive_fall { return K_PROCESS_DRIVE_FALL; }
|
||||||
|
k_process_drive_rise { return K_PROCESS_DRIVE_RISE; }
|
||||||
|
k_process_intrinsic_fall { return K_PROCESS_INTRINSIC_FALL; }
|
||||||
|
k_process_intrinsic_rise { return K_PROCESS_INTRINSIC_RISE; }
|
||||||
|
k_process_pin_cap { return K_PROCESS_PIN_CAP; }
|
||||||
|
k_process_slope_fall { return K_PROCESS_SLOPE_FALL; }
|
||||||
|
k_process_slope_rise { return K_PROCESS_SLOPE_RISE; }
|
||||||
|
k_process_wire_cap { return K_PROCESS_WIRE_CAP; }
|
||||||
|
k_process_wire_res { return K_PROCESS_WIRE_RES; }
|
||||||
|
k_temp_drive_fall { return K_TEMP_DRIVE_FALL; }
|
||||||
|
k_temp_drive_rise { return K_TEMP_DRIVE_RISE; }
|
||||||
|
k_temp_intrinsic_fall { return K_TEMP_INTRINSIC_FALL; }
|
||||||
|
k_temp_intrinsic_rise { return K_TEMP_INTRINSIC_RISE; }
|
||||||
|
k_temp_pin_cap { return K_TEMP_PIN_CAP; }
|
||||||
|
k_temp_slope_fall { return K_TEMP_SLOPE_FALL; }
|
||||||
|
k_temp_slope_rise { return K_TEMP_SLOPE_RISE; }
|
||||||
|
k_temp_wire_cap { return K_TEMP_WIRE_CAP; }
|
||||||
|
k_temp_wire_res { return K_TEMP_WIRE_RES; }
|
||||||
|
k_volt_drive_fall { return K_VOLT_DRIVE_FALL; }
|
||||||
|
k_volt_drive_rise { return K_VOLT_DRIVE_RISE; }
|
||||||
|
k_volt_intrinsic_fall { return K_VOLT_INTRINSIC_FALL; }
|
||||||
|
k_volt_intrinsic_rise { return K_VOLT_INTRINSIC_RISE; }
|
||||||
|
k_volt_pin_cap { return K_VOLT_PIN_CAP; }
|
||||||
|
k_volt_slope_fall { return K_VOLT_SLOPE_FALL; }
|
||||||
|
k_volt_slope_rise { return K_VOLT_SLOPE_RISE; }
|
||||||
|
k_volt_wire_cap { return K_VOLT_WIRE_CAP; }
|
||||||
|
k_volt_wire_res { return K_VOLT_WIRE_RES; }
|
||||||
|
time_unit { return TIME_UNIT; }
|
||||||
|
voltage_unit { return VOLTAGE_UNIT; }
|
||||||
|
current_unit { return CURRENT_UNIT; }
|
||||||
|
pulling_resistance_unit { return PULLING_RESISTANCE_UNIT; }
|
||||||
|
capacitive_load_unit { return CAPACITIVE_LOAD_UNIT; }
|
||||||
|
nom_process { return NOM_PROCESS; }
|
||||||
|
nom_temperature { return NOM_TEMPERATURE; }
|
||||||
|
nom_voltage { return NOM_VOLTAGE; }
|
||||||
|
in_place_swap_mode { return IN_PLACE_SWAP_MODE; }
|
||||||
|
|
||||||
|
wire_load { return WIRE_LOAD; }
|
||||||
|
resistance { return RESISTANCE; }
|
||||||
|
capacitance { return CAPACITANCE; }
|
||||||
|
area { return AREA; }
|
||||||
|
slope { return SLOPE; }
|
||||||
|
fanout_length { return FANOUT_LENGTH; }
|
||||||
|
wire_load_selection { return WIRE_LOAD_SELECTION; }
|
||||||
|
wire_load_from_area { return WIRE_LOAD_FROM_AREA; }
|
||||||
|
default_wire_load_selection { return DEFAULT_WIRE_LOAD_SELECTION; }
|
||||||
|
|
||||||
|
cell { return CELL; }
|
||||||
|
cell_footprint { return CELL_FOOTPRINT; }
|
||||||
|
dont_use { return DONT_USE; }
|
||||||
|
pin { return PIN; }
|
||||||
|
direction { return DIRECTION; }
|
||||||
|
capacitance { return CAPACITANCE; }
|
||||||
|
fanout_load { return FANOUT_LOAD; }
|
||||||
|
max_fanout { return MAX_FANOUT; }
|
||||||
|
function { return FUNCTION; }
|
||||||
|
three_state { return THREE_STATE; }
|
||||||
|
driver_type { return DRIVER_TYPE; }
|
||||||
|
timing { return TIMING; }
|
||||||
|
timing_sense { return TIMING_SENSE; }
|
||||||
|
timing_type { return TIMING_TYPE; }
|
||||||
|
intrinsic_rise { return INTRINSIC_RISE; }
|
||||||
|
intrinsic_fall { return INTRINSIC_FALL; }
|
||||||
|
rise_resistance { return RISE_RESISTANCE; }
|
||||||
|
fall_resistance { return FALL_RESISTANCE; }
|
||||||
|
related_pin { return RELATED_PIN; }
|
||||||
|
ff { return FF; }
|
||||||
|
next_state { return NEXT_STATE; }
|
||||||
|
clocked_on { return CLOCKED_ON; }
|
||||||
|
test_cell { return TEST_CELL; }
|
||||||
|
signal_type { return SIGNAL_TYPE; }
|
||||||
|
|
||||||
|
{FLOAT} { floatToken = atof(yytext); Liberty_lval._value = floatToken; return FLOAT; }
|
||||||
|
{STRING_NAME} { nameToken = yytext; Liberty_lval._text = nameToken.c_str(); return STRING_NAME; }
|
||||||
|
{STRING_DATE} { nameToken = yytext; Liberty_lval._text = nameToken.c_str(); return STRING_DATE; }
|
||||||
|
{STRING_UNIT} { nameToken = yytext; Liberty_lval._text = nameToken.c_str(); return STRING_UNIT; }
|
||||||
|
{STRING_FUNCTION} { nameToken = yytext; Liberty_lval._text = nameToken.c_str(); return STRING_FUNCTION; }
|
||||||
|
{STRING_FF} { nameToken = yytext; Liberty_lval._text = nameToken.c_str(); return STRING_FF; }
|
||||||
|
|
||||||
|
. { /* std::cerr << "autre :" << yytext << std::endl;*/ return *yytext; /* else */ }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int yywrap () { return 1; }
|
|
@ -0,0 +1,137 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
#include<ctime>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoad.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoadSelection.h"
|
||||||
|
#include "vlsisapd/liberty/Cell.h"
|
||||||
|
#include "vlsisapd/liberty/Library.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
Library::Library(Name name): _name(name), _attributes(), _wires_load(), _wire_load_selection(NULL), _cells() {};
|
||||||
|
|
||||||
|
Cell* Library::getCell(Name cellName) {
|
||||||
|
Cell* cell = NULL;
|
||||||
|
map<Name, Cell*>::iterator it = _cells.find(cellName);
|
||||||
|
if (it == _cells.end()) {
|
||||||
|
cerr << "[ERROR] No cell named " << cellName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
cell= (*it).second;
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
WireLoad* Library::getWireLoad(Name wireLoadName) {
|
||||||
|
WireLoad* wire = NULL;
|
||||||
|
map<Name, WireLoad*>::iterator it = _wires_load.find(wireLoadName);
|
||||||
|
if (it == _wires_load.end()) {
|
||||||
|
cerr << "[ERROR] No wire_load named " << wireLoadName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
wire= (*it).second;
|
||||||
|
return wire;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Library::addAttribute(Name attrName, Attribute::Type attrType, string& attrValue, const string& attrUnit) {
|
||||||
|
Attribute* attr = new Attribute(attrName, attrType, attrValue, attrUnit);
|
||||||
|
map<Name, Attribute*>::iterator it = _attributes.find(attrName);
|
||||||
|
if (it != _attributes.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define two Libraries's attributes with the same name: " << attrName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_attributes[attrName] = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Library::addWireLoad(Name wireLoadName) {
|
||||||
|
WireLoad* wire = new WireLoad(wireLoadName);
|
||||||
|
map<Name, WireLoad*>::iterator it = _wires_load.find(wireLoadName);
|
||||||
|
if (it != _wires_load.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define two Libraries's wire_load with the same name: " << wireLoadName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_wires_load[wireLoadName] = wire;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Library::addWireLoadSelection(Name wireLoadSelectionName) {
|
||||||
|
WireLoadSelection* wire = new WireLoadSelection(wireLoadSelectionName);
|
||||||
|
_wire_load_selection = wire;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Library::addCell(Name cellName) {
|
||||||
|
Cell* cell = new Cell(cellName);
|
||||||
|
map<Name, Cell*>::iterator it = _cells.find(cellName);
|
||||||
|
if (it != _cells.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define two Libraries's cells with the same name: " << cellName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_cells[cellName] = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Library::print() {
|
||||||
|
cout << "+-----------------------------+" << endl
|
||||||
|
<< "| Library name= " << _name.getString() << endl;
|
||||||
|
|
||||||
|
// Library's attributes
|
||||||
|
cout << "| Attributes :" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
cout << "| name= " << (*it).first.getString()
|
||||||
|
<< ", type= " << (*it).second->typeToString((*it).second->getType())
|
||||||
|
<< ", value= " << (*it).second->valueAsString();
|
||||||
|
string unit = (*it).second->getUnit();
|
||||||
|
if(!unit.empty())
|
||||||
|
cout << ", unit= " << unit;
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
// WireLoad
|
||||||
|
for(map<Name, WireLoad*>::const_iterator it=_wires_load.begin() ; it!=_wires_load.end() ; ++it) {
|
||||||
|
(*it).second->print();
|
||||||
|
}
|
||||||
|
// WireLoadSelection
|
||||||
|
_wire_load_selection->print();
|
||||||
|
// Cell
|
||||||
|
for(map<Name, Cell*>::const_iterator it=_cells.begin() ; it!=_cells.end() ; ++it) {
|
||||||
|
(*it).second->print();
|
||||||
|
}
|
||||||
|
cout << "+-----------------------------+" << endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool Library::writeToFile(string filename) {
|
||||||
|
time_t curtime = time(0);
|
||||||
|
tm now = *localtime(&curtime);
|
||||||
|
char date[BUFSIZ]={0};
|
||||||
|
const char format[]="%y-%m-%d %H:%M:%S";
|
||||||
|
if (!strftime(date, sizeof(date)-1, format, &now)>0)
|
||||||
|
cerr << "[Liberty DRIVE ERROR]: cannot build current date." << endl;
|
||||||
|
|
||||||
|
ofstream file;
|
||||||
|
file.open(filename.c_str(), ios::out);
|
||||||
|
// Header
|
||||||
|
file << "/* Generated by vlsisapd driver */" << endl
|
||||||
|
<< "/* date : " << date << " */" << endl;
|
||||||
|
file << "library (" << _name.getString() << ") {" << endl;
|
||||||
|
|
||||||
|
// Library's attributes
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
file << " ";
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
// For each WireLoad : write wireload
|
||||||
|
for(map<Name, WireLoad*>::const_iterator it=_wires_load.begin() ; it!=_wires_load.end() ; ++it) {
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
// write wireloadselection
|
||||||
|
_wire_load_selection->write(file);
|
||||||
|
// for each Cell : write cell
|
||||||
|
for(map<Name, Cell*>::const_iterator it=_cells.begin() ; it!=_cells.end() ; ++it) {
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
// Footer
|
||||||
|
file << "}" << endl;
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
|
@ -0,0 +1,59 @@
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
unsigned long Name::_globalId = 0;
|
||||||
|
map<string, unsigned long> Name::_dict;
|
||||||
|
|
||||||
|
Name::Name() : _str(NULL) {
|
||||||
|
map<string, unsigned long>::iterator it = _dict.find("");
|
||||||
|
if (it != _dict.end()) {
|
||||||
|
_id = (*it).second;
|
||||||
|
_str = &((*it).first);
|
||||||
|
} else {
|
||||||
|
_id = _globalId++;
|
||||||
|
it = _dict.insert(_dict.begin(), make_pair("", _id));
|
||||||
|
_str = &((*it).first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Name::Name(string str) : _str(NULL) {
|
||||||
|
map<string, unsigned long>::iterator it = _dict.find(str);
|
||||||
|
if (it != _dict.end()) {
|
||||||
|
_id = (*it).second;
|
||||||
|
_str = &((*it).first);
|
||||||
|
} else {
|
||||||
|
_id = _globalId++;
|
||||||
|
it = _dict.insert(_dict.begin(), make_pair(str, _id));
|
||||||
|
_str = &((*it).first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Name::Name(const char* c) : _str(NULL) {
|
||||||
|
string str(c);
|
||||||
|
map<string, unsigned long>::iterator it = _dict.find(str);
|
||||||
|
if (it != _dict.end()) {
|
||||||
|
_id = (*it).second;
|
||||||
|
_str = &((*it).first);
|
||||||
|
} else {
|
||||||
|
_id = _globalId++;
|
||||||
|
it = _dict.insert(_dict.begin(), make_pair(str, _id));
|
||||||
|
_str = &((*it).first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Name::operator==(const Name& n) {
|
||||||
|
return (_id == n._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Name::operator==(const string& str) {
|
||||||
|
Name n(str);
|
||||||
|
return (_id == n._id);
|
||||||
|
}
|
||||||
|
bool Name::operator<(const Name& n) const {
|
||||||
|
//return (_id < n._id); // does not assert determinism in driving since hurricane do not care about name's ID --> need an alphabetical check on string
|
||||||
|
return (*_str < n.getString());
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Pin.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
Pin::Pin(Name name): _name(name), _attributes(), _timings() {};
|
||||||
|
|
||||||
|
void Pin::addAttribute(Name attrName, Attribute::Type attrType, string& attrValue) {
|
||||||
|
Attribute* attr = new Attribute(attrName, attrType, attrValue);
|
||||||
|
map<Name, Attribute*>::iterator it = _attributes.find(attrName);
|
||||||
|
if (it != _attributes.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define Pin " << _name.getString() << " with several attributes with the same name: " << attrName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_attributes[attrName] = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pin::addTiming() {
|
||||||
|
Timing* timing = new Timing();
|
||||||
|
_timings.push_back(timing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pin::print() {
|
||||||
|
cout << "| Pin name= " << _name.getString() << endl;
|
||||||
|
|
||||||
|
// Pin's attributes
|
||||||
|
cout << "| Attributes :" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
cout << "| name= " << (*it).first.getString()
|
||||||
|
<< ", type= " << (*it).second->typeToString((*it).second->getType())
|
||||||
|
<< ", value= " << (*it).second->valueAsString() << endl;
|
||||||
|
}
|
||||||
|
// Timing
|
||||||
|
for (size_t i = 0 ; i < _timings.size() ; i++) {
|
||||||
|
_timings[i]->print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pin::write(ofstream &file) {
|
||||||
|
file << " pin(" << _name.getString() << ") {" << endl;
|
||||||
|
//Pin's attributes
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
file << " ";
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
// Timing
|
||||||
|
for (size_t i = 0 ; i < _timings.size() ; i++)
|
||||||
|
_timings[i]->write(file);
|
||||||
|
file << " }" << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Timing.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
Timing::Timing(): _attributes() {};
|
||||||
|
|
||||||
|
void Timing::addAttribute(Name attrName, Attribute::Type attrType, string& attrValue) {
|
||||||
|
Attribute* attr = new Attribute(attrName, attrType, attrValue);
|
||||||
|
map<Name, Attribute*>::iterator it = _attributes.find(attrName);
|
||||||
|
if (it != _attributes.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define Timing with several attributes with the same name : " << attrName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_attributes[attrName] = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timing::print() {
|
||||||
|
// Timing's attributes
|
||||||
|
cout << "| Timing's attributes :" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
cout << "| name= " << (*it).first.getString()
|
||||||
|
<< ", type= " << (*it).second->typeToString((*it).second->getType())
|
||||||
|
<< ", value= " << (*it).second->valueAsString() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Timing::write(ofstream &file) {
|
||||||
|
file << " timing() {" << endl;
|
||||||
|
// Timing's attributes
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
file << " ";
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
file << " }" << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoad.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
WireLoad::WireLoad(Name name): _name(name), _attributes() {};
|
||||||
|
|
||||||
|
void WireLoad::addAttribute(Name attrName, Attribute::Type attrType, string& attrValue, const string& attrValue2) {
|
||||||
|
Attribute* attr = new Attribute(attrName, attrType, attrValue, "", attrValue2);
|
||||||
|
map<Name, Attribute*>::iterator it = _attributes.find(attrName);
|
||||||
|
if (it != _attributes.end()) {
|
||||||
|
cerr << "[ERROR] Cannot define WireLoad with several attributes with the same name : " << attrName.getString() << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_attributes[attrName] = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireLoad::print() {
|
||||||
|
// WireLoad's attributes
|
||||||
|
cout << "| Wireload : " << _name.getString() << endl;
|
||||||
|
cout << "| Attributes :" << endl;
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it) {
|
||||||
|
cout << "| name= " << (*it).first.getString()
|
||||||
|
<< ", type= " << (*it).second->typeToString((*it).second->getType())
|
||||||
|
<< ", value= " << (*it).second->valueAsString();
|
||||||
|
string value2=(*it).second->secondValueAsString();
|
||||||
|
if(!value2.empty())
|
||||||
|
cout << ", value2= " << value2;
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WireLoad::write(ofstream &file) {
|
||||||
|
file << " wire_load(\"" << _name.getString() << "\") {" << endl;
|
||||||
|
|
||||||
|
for(map<Name, Attribute*>::const_iterator it=_attributes.begin() ; it!=_attributes.end() ; ++it ) {
|
||||||
|
file << " ";
|
||||||
|
(*it).second->write(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
file << "}" << endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include<fstream>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoadArea.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
WireLoadArea::WireLoadArea(double min, double max, Name name): _min(min), _max(max), _name(name) {};
|
||||||
|
|
||||||
|
bool WireLoadArea::write(std::ofstream &file) {
|
||||||
|
file << "wire_load_from_area(" << _min << "," << _max << ",\"" << _name.getString() << "\");" << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include<iostream>
|
||||||
|
#include<fstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoadSelection.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
WireLoadSelection::WireLoadSelection(Name name): _name(name), _wires_load_area() {};
|
||||||
|
|
||||||
|
void WireLoadSelection::addWireLoadArea(double min, double max, Name name) {
|
||||||
|
WireLoadArea * area = new WireLoadArea(min, max, name);
|
||||||
|
_wires_load_area.push_back(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireLoadSelection::print() {
|
||||||
|
cout << "| WireLoadSection name= " << _name.getString() << endl;
|
||||||
|
for(size_t i = 0 ; i < _wires_load_area.size() ; i++) {
|
||||||
|
cout << "| wire_load_from_area name= " << _wires_load_area[i]->getName().getString()
|
||||||
|
<< ", min= " << _wires_load_area[i]->getMin()
|
||||||
|
<< ", max= " << _wires_load_area[i]->getMax()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WireLoadSelection::write(ofstream& file) {
|
||||||
|
file << " wire_load_selection(" << _name.getString() << ") {" << endl;
|
||||||
|
|
||||||
|
for(size_t i = 0 ; i < _wires_load_area.size() ; i++) {
|
||||||
|
file << " ";
|
||||||
|
_wires_load_area[i]->write(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
file << "}" << endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef __LIB_ATTRIBUTE_H__
|
||||||
|
#define __LIB_ATTRIBUTE_H__
|
||||||
|
|
||||||
|
#include<string>
|
||||||
|
#include<fstream>
|
||||||
|
#include "Name.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
class Attribute {
|
||||||
|
public:
|
||||||
|
enum Type { Unknown = 0
|
||||||
|
, String = 1
|
||||||
|
, Bool = 2
|
||||||
|
, Int = 3
|
||||||
|
, Double = 4
|
||||||
|
, Unit = 5
|
||||||
|
, Pair = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Attribute(const Name name, Type type, const std::string& value, const std::string& unit="", const std::string& value2="");
|
||||||
|
|
||||||
|
inline const Name getName() const;
|
||||||
|
inline const Type getType() const;
|
||||||
|
inline const std::string& getUnit() const;
|
||||||
|
|
||||||
|
inline const std::string& valueAsString() const;
|
||||||
|
inline const std::string& secondValueAsString() const;
|
||||||
|
bool valueAsBool() const;
|
||||||
|
int valueAsInt() const;
|
||||||
|
double valueAsDouble() const;
|
||||||
|
double secondValueAsDouble() const;
|
||||||
|
std::string typeToString(Type type);
|
||||||
|
bool write(std::ofstream &file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _name;
|
||||||
|
Type _type;
|
||||||
|
std::string _value;
|
||||||
|
std::string _unit;
|
||||||
|
std::string _value2;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const std::string& Attribute::getUnit() const { return _unit; }
|
||||||
|
inline const Name Attribute::getName() const { return _name; }
|
||||||
|
inline const Attribute::Type Attribute::getType() const { return _type; }
|
||||||
|
inline const std::string& Attribute::valueAsString() const { return _value; }
|
||||||
|
inline const std::string& Attribute::secondValueAsString() const { return _value2; }
|
||||||
|
} // namespace
|
||||||
|
#endif
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef __LIB_CELL_H__
|
||||||
|
#define __LIB_CELL_H__
|
||||||
|
|
||||||
|
#include<fstream>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Pin.h"
|
||||||
|
#include "vlsisapd/liberty/FlipFlop.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class Cell {
|
||||||
|
public:
|
||||||
|
Cell(Name name);
|
||||||
|
|
||||||
|
inline Name getName();
|
||||||
|
Pin* getPin(Name pinName);
|
||||||
|
inline FlipFlop* getFF();
|
||||||
|
|
||||||
|
void addAttribute(Name attrName, Attribute::Type attrType, std::string& attrValue);
|
||||||
|
void addPin(Name pinName);
|
||||||
|
void addFF(Name noninverting, Name inverting);
|
||||||
|
void setTestCell(Cell *cell);
|
||||||
|
|
||||||
|
void print();
|
||||||
|
bool write(std::ofstream &file, bool test=false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _name;
|
||||||
|
std::map<Name, Attribute*> _attributes;
|
||||||
|
std::map<Name, Pin*> _pins;
|
||||||
|
FlipFlop* _ff;
|
||||||
|
Cell* _test_cell;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Name Cell::getName() { return _name; };
|
||||||
|
inline FlipFlop* Cell::getFF() { return _ff; };
|
||||||
|
|
||||||
|
} // namespace LIB
|
||||||
|
#endif
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef __LIB_FLIP_FLOP_H__
|
||||||
|
#define __LIB_FLIP_FLOP_H__
|
||||||
|
|
||||||
|
#include<fstream>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class FlipFlop {
|
||||||
|
public:
|
||||||
|
FlipFlop(Name noninverting, Name inverting);
|
||||||
|
|
||||||
|
void addAttribute(Name attrName, Attribute::Type attrType, std::string& attrValue);
|
||||||
|
|
||||||
|
void print();
|
||||||
|
bool write(std::ofstream &file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _noninverting;
|
||||||
|
Name _inverting;
|
||||||
|
std::map<Name, Attribute*> _attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LIB
|
||||||
|
#endif
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef __LIB_LIBRARY_H__
|
||||||
|
#define __LIB_LIBRARY_H__
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoad.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoadSelection.h"
|
||||||
|
#include "vlsisapd/liberty/Cell.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class Library {
|
||||||
|
public:
|
||||||
|
Library(Name name);
|
||||||
|
|
||||||
|
inline Name getName();
|
||||||
|
Cell* getCell(Name cellName);
|
||||||
|
WireLoad* getWireLoad(Name wireLoadName);
|
||||||
|
inline WireLoadSelection* getWireLoadSelection();
|
||||||
|
|
||||||
|
void addAttribute(Name attrName, Attribute::Type attrType, std::string& attrValue, const std::string& attrUnit="");
|
||||||
|
void addWireLoad(Name wireLoadName);
|
||||||
|
void addWireLoadSelection(Name wireLoadSelectionName);
|
||||||
|
void addCell(Name cellName);
|
||||||
|
|
||||||
|
void print();
|
||||||
|
|
||||||
|
static Library* readFromFile(std::string);
|
||||||
|
bool writeToFile ( std::string fileName );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _name;
|
||||||
|
std::map<Name, Attribute*> _attributes;
|
||||||
|
std::map<Name, WireLoad*> _wires_load;
|
||||||
|
WireLoadSelection* _wire_load_selection;
|
||||||
|
std::map<Name, Cell*> _cells;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Name Library::getName() { return _name; };
|
||||||
|
inline WireLoadSelection* Library::getWireLoadSelection() { return _wire_load_selection; };
|
||||||
|
|
||||||
|
} // namespace LIB
|
||||||
|
#endif
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Name.h
|
||||||
|
* openChams
|
||||||
|
*
|
||||||
|
* Created by damien dupuis on 18/12/09.
|
||||||
|
* Copyright 2009 UPMC / LIP6. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LIB_NAME_H__
|
||||||
|
#define __LIB_NAME_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
class Name {
|
||||||
|
public:
|
||||||
|
Name();
|
||||||
|
Name(std::string);
|
||||||
|
Name(const char*);
|
||||||
|
|
||||||
|
bool operator==(const Name&);
|
||||||
|
bool operator==(const std::string&);
|
||||||
|
bool operator<(const Name&) const;
|
||||||
|
|
||||||
|
inline const std::string& getString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned long _id;
|
||||||
|
const std::string *_str;
|
||||||
|
|
||||||
|
static std::map<std::string, unsigned long> _dict;
|
||||||
|
static unsigned long _globalId;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const std::string& Name::getString() const{
|
||||||
|
if (!_str) {
|
||||||
|
//throw LIBException("[ERROR] Name object has no string");
|
||||||
|
}
|
||||||
|
return *_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef __LIB_PIN_H__
|
||||||
|
#define __LIB_PIN_H__
|
||||||
|
|
||||||
|
#include<fstream>
|
||||||
|
#include<vector>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
#include "vlsisapd/liberty/Timing.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class Pin {
|
||||||
|
public:
|
||||||
|
Pin(Name name);
|
||||||
|
|
||||||
|
inline Name getName();
|
||||||
|
inline std::vector<Timing*> getTiming();
|
||||||
|
|
||||||
|
void addAttribute(Name attrName, Attribute::Type attrType, std::string& attrValue);
|
||||||
|
void addTiming();
|
||||||
|
|
||||||
|
void print();
|
||||||
|
bool write(std::ofstream &file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _name;
|
||||||
|
std::map<Name, Attribute*> _attributes;
|
||||||
|
std::vector<Timing*> _timings;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Name Pin::getName() { return _name; };
|
||||||
|
inline std::vector<Timing*> Pin::getTiming() { return _timings; };
|
||||||
|
|
||||||
|
} // namespace LIB
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef __LIB_TIMING_H__
|
||||||
|
#define __LIB_TIMING_H__
|
||||||
|
|
||||||
|
#include<fstream>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class Timing {
|
||||||
|
public:
|
||||||
|
Timing();
|
||||||
|
|
||||||
|
void addAttribute(Name attrName, Attribute::Type attrType, std::string& attrValue);
|
||||||
|
|
||||||
|
void print();
|
||||||
|
bool write(std::ofstream &file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<Name, Attribute*> _attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LIB
|
||||||
|
#endif
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef __LIB_WIRE_LOAD_H__
|
||||||
|
#define __LIB_WIRE_LOAD_H__
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/Attribute.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class WireLoad {
|
||||||
|
public:
|
||||||
|
WireLoad(Name name);
|
||||||
|
|
||||||
|
inline Name getName();
|
||||||
|
|
||||||
|
void addAttribute(Name attrName, Attribute::Type attrType, std::string& attrValue, const std::string& attrValue2 = "");
|
||||||
|
|
||||||
|
void print();
|
||||||
|
bool write(std::ofstream &file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _name;
|
||||||
|
std::map<Name, Attribute*> _attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Name WireLoad::getName() { return _name; };
|
||||||
|
|
||||||
|
} // namespace LIB
|
||||||
|
#endif
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __LIB_WIRE_LOAD_AREA_H__
|
||||||
|
#define __LIB_WIRE_LOAD_AREA_H__
|
||||||
|
|
||||||
|
#include<fstream>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class WireLoadArea {
|
||||||
|
public:
|
||||||
|
WireLoadArea(double min, double max, Name name);
|
||||||
|
|
||||||
|
inline double getMin();
|
||||||
|
inline double getMax();
|
||||||
|
inline Name getName();
|
||||||
|
|
||||||
|
bool write(std::ofstream &file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double _min;
|
||||||
|
double _max;
|
||||||
|
Name _name;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline double WireLoadArea::getMin() { return _min; };
|
||||||
|
inline double WireLoadArea::getMax() { return _max; };
|
||||||
|
inline Name WireLoadArea::getName() { return _name; };
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
#endif
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef __LIB_WIRE_LOAD_SELECTION_H__
|
||||||
|
#define __LIB_WIRE_LOAD_SELECTION_H__
|
||||||
|
|
||||||
|
#include<vector>
|
||||||
|
#include<fstream>
|
||||||
|
|
||||||
|
#include "vlsisapd/liberty/Name.h"
|
||||||
|
#include "vlsisapd/liberty/WireLoadArea.h"
|
||||||
|
|
||||||
|
namespace LIB {
|
||||||
|
|
||||||
|
class WireLoadSelection {
|
||||||
|
public:
|
||||||
|
WireLoadSelection(Name name);
|
||||||
|
|
||||||
|
void addWireLoadArea(double min, double max, Name name);
|
||||||
|
void print();
|
||||||
|
bool write(std::ofstream& file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Name _name;
|
||||||
|
std::vector<WireLoadArea*> _wires_load_area;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
#endif
|
Loading…
Reference in New Issue