* ./crlcore:

- New: Added support for ACM/SIGDA ISCAS98 (.bench extension).
    - Bug: In Parsers/Drivers changes the signature of the prototype, passes
        file name string by value instead of by reference. In the cases of
        reentrant P&D calls it may causes havoc.
This commit is contained in:
Jean-Paul Chaput 2010-07-30 16:31:27 +00:00
parent 32c864b996
commit cdbfff194d
30 changed files with 495 additions and 39 deletions

View File

@ -15,6 +15,7 @@
${CRLCORE_SOURCE_DIR}/src/ccore
${CRLCORE_SOURCE_DIR}/src/ccore/properties
${CRLCORE_SOURCE_DIR}/src/ccore/bookshelf
${CRLCORE_SOURCE_DIR}/src/ccore/acmsigda
${CRLCORE_SOURCE_DIR}/src/ccore/cspice
${CRLCORE_SOURCE_DIR}/src/ccore/lefdef
${CRLCORE_SOURCE_DIR}/src/ccore/alliance/ap
@ -223,6 +224,34 @@
# set_source_files_properties ( ${LibertyParserScannerCpp} GENERATED )
# set_source_files_properties ( ${LibertyParserGrammarCpp} GENERATED )
set ( AcmSigdaParserSourceDir ${CRLCORE_SOURCE_DIR}/src/ccore/acmsigda )
set ( AcmSigdaParserBinaryDir ${CRLCORE_BINARY_DIR}/src/ccore/acmsigda )
set ( AcmSigdaParserScanner ${AcmSigdaParserSourceDir}/AcmSigdaParserScanner.ll )
set ( AcmSigdaParserGrammar ${AcmSigdaParserSourceDir}/AcmSigdaParserGrammar.yy )
set ( AcmSigdaParserScannerCpp ${AcmSigdaParserBinaryDir}/AcmSigdaParserScanner.cpp )
set ( AcmSigdaParserGrammarCpp ${AcmSigdaParserBinaryDir}/AcmSigdaParserGrammar.cpp )
add_subdirectory ( acmsigda )
add_custom_target ( AcmSigdaParser echo "Creating ACM/SIGDA parser" )
add_custom_command ( SOURCE ${AcmSigdaParserScanner}
COMMAND ${FLEX_EXECUTABLE}
ARGS -PAcmSigda_ -o${AcmSigdaParserScannerCpp} ${AcmSigdaParserScanner}
TARGET AcmSigdaParser
OUTPUTS ${AcmSigdaParserScannerCpp}
)
add_custom_command ( SOURCE ${AcmSigdaParserGrammar}
COMMAND ${BISON_EXECUTABLE}
ARGS -d -v -p AcmSigda_ -y ${AcmSigdaParserGrammar} -o ${AcmSigdaParserGrammarCpp}
TARGET AcmSigdaParser
DEPENDS ${AcmSigdaParserScannerCpp}
OUTPUTS ${AcmSigdaParserGrammarCpp}
)
include_directories ( ${AcmSigdaParserBinaryDir} )
set ( acmsigda_parser_cpps ${AcmSigdaParserScannerCpp}
${AcmSigdaParserGrammarCpp}
)
set_source_files_properties ( ${AcmSigdaParserScannerCpp} GENERATED )
set_source_files_properties ( ${AcmSigdaParserGrammarCpp} GENERATED )
qt4_wrap_cpp ( moc_cpps ${mocincludes} )
@ -239,6 +268,7 @@
${liberty_cpps}
${liberty_parser_cpps}
${bookshelf_cpps}
${acmsigda_parser_cpps}
${spice_cpps}
${lefdef_cpps}
${openaccess_cpps}

View File

@ -706,6 +706,7 @@ namespace CRL {
bool coherency = false;
if ( ( _IN_LO == "vst" ) && ( _IN_PH == "ap" ) ) coherency = true;
else if ( ( _IN_LO == "spi" ) && ( _IN_PH == "ap" ) ) coherency = true;
else if ( ( _IN_LO == "bench" ) && ( _IN_PH == "ap" ) ) coherency = true;
else if ( ( _IN_LO == "def" ) && ( _IN_PH == "def") ) coherency = true;
else if ( ( _IN_LO == "aux" ) && ( _IN_PH == "aux") ) coherency = true;
else if ( ( _IN_LO == "oa" ) && ( _IN_PH == "oa" ) ) coherency = true;

View File

@ -61,6 +61,7 @@
# include "Vst.h"
# include "Spice.h"
# include "Bookshelf.h"
# include "AcmSigda.h"
# include "LefDef.h"
# include "openaccess/OpenAccess.h"
@ -222,6 +223,7 @@ namespace CRL {
registerSlot ( "oa", (CellParser_t*)OpenAccess::oaCellParser , "oa" );
registerSlot ( "oa", (LibraryParser_t*)OpenAccess::oaLibParser , "oa" );
registerSlot ( "aux", (CellParser_t*)bookshelfParser, "aux" );
registerSlot ( "bench", (CellParser_t*)acmSigdaParser , "bench" );
}

View File

@ -0,0 +1,24 @@
#include <string>
namespace Hurricane {
class Cell;
}
#ifndef __ACM_SIGDA_H__
#define __ACM_SIGDA_H__
namespace CRL {
// -------------------------------------------------------------------
// functions.
void acmSigdaParser ( const std::string cellPath, Hurricane::Cell* cell );
}
# endif

View File

@ -0,0 +1,358 @@
%{
#include <cstdio>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#include "hurricane/Net.h"
#include "hurricane/Cell.h"
#include "hurricane/Plug.h"
#include "hurricane/Instance.h"
#include "hurricane/UpdateSession.h"
using namespace Hurricane;
#include "crlcore/Utilities.h"
#include "crlcore/Catalog.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/NetExtension.h"
#include "AcmSigda.h"
using namespace CRL;
// Symbols from Flex which should be substituted.
#define yyrestart AcmSigda_restart
#define yytext AcmSigda_text
#define yywrap AcmSigda_wrap
#define yyin AcmSigda_in
extern char* yytext;
extern FILE* yyin;
extern int yylineno;
extern int yylex ();
extern int yywrap ();
extern void yyrestart ( FILE* );
namespace {
int AcmSigda_error ( char* message );
class ParserState {
public:
Cell* _cell;
Catalog::State* _state;
vector<string> _inputs;
string _output;
int _gateType;
public:
inline ParserState ();
inline void reset ();
};
inline ParserState::ParserState () : _cell (NULL)
, _state (NULL)
, _inputs ()
, _output ()
, _gateType(0)
{ }
inline void ParserState::reset ()
{
_cell = NULL;
_state = NULL;
_inputs.clear ();
_output = "";
_gateType = 0;
}
ParserState __state;
AllianceFramework* __framework;
Net* getNet ( Cell* cell
, const string& name
, Net::Direction direction=Net::Direction::UNDEFINED
, bool create =false )
{
Net* net = cell->getNet ( Name(name) );
if ( net == NULL ) {
if ( not create )
throw Error ( "AcmSigdaParserGrammar(), line %d:\n"
" No net \"%s\" in cell \"%s\".\n"
, yylineno
, name.c_str()
, getString(cell->getName()).c_str()
);
net = Net::create ( __state._cell, name.c_str() );
net->setDirection ( direction );
}
return net;
}
Instance* createInstance ();
} // End of local namespace.
%}
%union { int _value;
const char *_text;
};
%token Equal
%token LeftParent
%token RightParent
%token Comma
%token <_value> AND
%token <_value> NAND
%token <_value> OR
%token <_value> NOR
%token <_value> INPUT
%token <_value> OUTPUT
%token <_value> NOT
%token <_value> FROM
%token <_value> XOR
%token <_value> XNOR
%token <_value> BUFF
%token <_value> DFF
%token <_text> NAME
%type <_value> type
%type <_value> primary_io
%start file
%%
file :
| line
| file line
;
line : primary_io LeftParent NAME RightParent
{
//if ($1 == INPUT) cout << "INPUT (" << $3 << ")" << endl;
//else cout << "OUTPUT(" << $3 << ")" << endl;
Net::Direction direction = ($1 == INPUT) ? Net::Direction::IN : Net::Direction::OUT ;
Net* net = getNet ( __state._cell, $3, direction, true );
net->setExternal ( true );
}
| output Equal type LeftParent inputs RightParent
{
__state._gateType = $3;
createInstance ();
__state._inputs.clear();
__state._output.clear();
}
;
primary_io : INPUT { $$ = $1; }
| OUTPUT { $$ = $1; }
;
inputs : NAME { __state._inputs.push_back ( $1 ); }
| inputs Comma NAME { __state._inputs.push_back ( $3 ); }
;
output : NAME { __state._output = $1; }
;
type : AND { $$ = $1; }
| NAND { $$ = $1; }
| OR { $$ = $1; }
| NOR { $$ = $1; }
| XOR { $$ = $1; }
| XNOR { $$ = $1; }
| BUFF { $$ = $1; }
| NOT { $$ = $1; }
| DFF { $$ = $1; }
;
%%
namespace {
Instance* createInstance ()
{
//cout << __state._output << " = " << __state._gateType << "(";
//for ( size_t i=0 ; i<__state._inputs.size() ; ++i ) {
// if ( i>0 ) cout << ",";
// cout << __state._inputs[i];
//}
//cout << ")" << endl;
const char* masterName = NULL;
const char* AndTable [3] = { "a2_x2", "a3_x2", "a4_x4" };
const char* NandTable [3] = { "na2_x1", "na3_x1", "na4_x1" };
const char* OrTable [3] = { "o2_x2", "o3_x2", "o4_x4" };
const char* NorTable [3] = { "no2_x1", "no3_x1", "no4_x1" };
size_t inputsNb = __state._inputs.size();
switch ( __state._gateType ) {
case AND: if ( (inputsNb > 1) and (inputsNb < 5) ) masterName = AndTable [inputsNb-2]; break;
case NAND: if ( (inputsNb > 1) and (inputsNb < 5) ) masterName = NandTable[inputsNb-2]; break;
case OR: if ( (inputsNb > 1) and (inputsNb < 5) ) masterName = OrTable [inputsNb-2]; break;
case NOR: if ( (inputsNb > 1) and (inputsNb < 5) ) masterName = NorTable [inputsNb-2]; break;
case XOR: masterName = "xr2_x1"; break;
case XNOR: masterName = "nxr2_x1"; break;
case BUFF: masterName = "buf_x2"; break;
case NOT: masterName = "inv_x1"; break;
case DFF: masterName = "sff1_x4"; break;
}
if ( masterName == NULL ) {
cerr << "[ERROR] Unmatched virtual cell " << __state._output << "." << endl;
return NULL;
}
Cell* masterCell = __framework->getCell(masterName,Catalog::State::Views);
Instance* instance = Instance::create ( __state._cell
, __state._output.c_str()
, masterCell );
// Inputs assignment.
switch ( __state._gateType ) {
case AND:
case NAND:
case OR:
case NOR:
case XOR:
case XNOR:
{
char terminal[3] = "iX";
for ( size_t i=0 ; i<inputsNb ; ++i ) {
terminal[1] = '0' + (char)i;
instance->getPlug ( masterCell->getNet(terminal) )->setNet ( getNet(__state._cell
, __state._inputs[i].c_str()
, Net::Direction::UNDEFINED
, true) );
}
}
break;
case DFF:
instance->getPlug ( masterCell->getNet("ck") )->setNet ( getNet(__state._cell
, "ck"
, Net::Direction::UNDEFINED
, true) );
case BUFF:
case NOT:
instance->getPlug ( masterCell->getNet("i") )->setNet ( getNet(__state._cell
, __state._inputs[0].c_str()
, Net::Direction::UNDEFINED
, true) );
break;
}
// Output assignment.
switch ( __state._gateType ) {
case AND:
case OR:
case XOR:
case BUFF:
case DFF:
instance->getPlug ( masterCell->getNet("q") )->setNet ( getNet(__state._cell
, __state._output.c_str()
, Net::Direction::UNDEFINED
, true) );
break;
case NAND:
case NOR:
case XNOR:
case NOT:
instance->getPlug ( masterCell->getNet("nq") )->setNet ( getNet(__state._cell
, __state._output.c_str()
, Net::Direction::UNDEFINED
, true) );
break;
}
return instance;
}
int AcmSigda_error ( char* message )
{
throw Error ( "AcmSigdaParser(): Syntax error at line %d.\n", yylineno );
return 0;
}
} // End of anonymous namespace.
namespace CRL {
void acmSigdaParser ( const string cellPath, Cell *cell )
{
cmess2 << " " << tab << "+ " << cellPath << endl; tab++;
static bool firstCall = true;
if ( firstCall ) {
firstCall = false;
__framework = AllianceFramework::get ();
// Preload SxLib using <vst> format.
__framework->getEnvironment()->setIN_LO ( "vst" );
__framework->loadLibraryCells ( "sxlib" );
__framework->getEnvironment()->setIN_LO ( "bench" );
}
CatalogProperty *sprop =
(CatalogProperty*)cell->getProperty ( CatalogProperty::getPropertyName() );
if ( sprop == NULL )
throw Error ( "Missing CatalogProperty in cell %s.\n" , getString(cell->getName()).c_str() );
__state._cell = cell;
__state._cell->setTerminal ( false );
__state._state = sprop->getState();
__state._state->setLogical ( true );
Net* net = getNet ( __state._cell, "vdd", Net::Direction::IN, true );
net->setExternal ( true );
net->setGlobal ( true );
net->setType ( Net::Type::POWER );
net = getNet ( __state._cell, "vss", Net::Direction::IN, true );
net->setExternal ( true );
net->setGlobal ( true );
net->setType ( Net::Type::GROUND );
net = getNet ( __state._cell, "ck", Net::Direction::IN, true );
net->setExternal ( true );
IoFile ccell ( cellPath );
ccell.open ( "r" );
yyin = ccell.getFile ();
if ( not firstCall ) yyrestart ( yyin );
UpdateSession::open ();
yyparse ();
UpdateSession::close ();
ccell.close ();
__state.reset ();
}
} // End of CRL namespace.

View File

@ -0,0 +1,41 @@
%{
#include <iostream>
#include <string>
#include "AcmSigdaParserGrammar.hpp"
static std::string nameToken;
int yylineno = 0;
%}
NAME [^ #(),\t\n]+
COMMENT #[^\n]*
%%
{COMMENT} { std::cout << yytext << std::endl; std::cout.flush(); }
= { return Equal; }
\( { return LeftParent; }
\) { return RightParent; }
\, { return Comma; }
INPUT { AcmSigda_lval._value = INPUT; return AcmSigda_lval._value; }
OUTPUT { AcmSigda_lval._value = OUTPUT; return AcmSigda_lval._value; }
AND { AcmSigda_lval._value = AND; return AcmSigda_lval._value; }
NAND { AcmSigda_lval._value = NAND; return AcmSigda_lval._value; }
OR { AcmSigda_lval._value = OR; return AcmSigda_lval._value; }
NOR { AcmSigda_lval._value = NOR; return AcmSigda_lval._value; }
XOR { AcmSigda_lval._value = XOR; return AcmSigda_lval._value; }
XNOR { AcmSigda_lval._value = XNOR; return AcmSigda_lval._value; }
BUFF { AcmSigda_lval._value = BUFF; return AcmSigda_lval._value; }
DFF { AcmSigda_lval._value = DFF; return AcmSigda_lval._value; }
(NOT|INV) { AcmSigda_lval._value = NOT; return AcmSigda_lval._value; }
{NAME} { nameToken = yytext; AcmSigda_lval._text = nameToken.c_str(); return NAME; }
\n { yylineno++; }
. { }
%%
int yywrap () { return 1; }

View File

@ -12,6 +12,6 @@ namespace Hurricane {
}
namespace CRL {
void agdsDriver(const std::string& filePath, Hurricane::Cell* cell, std::string& name, std::string& lib, double& uUnits, double& pUnits);
void agdsDriver(const std::string filePath, Hurricane::Cell* cell, std::string& name, std::string& lib, double& uUnits, double& pUnits);
}
# endif

View File

@ -85,7 +85,7 @@ void AgdsQuery::goCallback(Go* go) {
} // namespace
namespace CRL {
void agdsDriver(const string& filePath, Cell* cell, string& name, string& lib, double& uUnits, double& pUnits) {
void agdsDriver(const string filePath, Cell* cell, string& name, string& lib, double& uUnits, double& pUnits) {
name = getString(cell->getName());
replace(name.begin(), name.end(), ' ', '_');
lib = getString(cell->getLibrary()->getName());

View File

@ -55,8 +55,8 @@ namespace CRL {
// -------------------------------------------------------------------
// functions.
void apParser ( const string& cellPath, Cell* cell );
void apDriver ( const string& cellPath, Cell* cell, unsigned int& saveState);
void apParser ( const string cellPath, Cell* cell );
void apDriver ( const string cellPath, Cell* cell, unsigned int& saveState);
}

View File

@ -423,7 +423,7 @@ void DumpInstances(ofstream &ccell, Cell* cell)
namespace CRL {
void apDriver( const string& cellPath, Cell *cell, unsigned int &saveState) {
void apDriver( const string cellPath, Cell *cell, unsigned int &saveState) {
::std::ofstream ccell ( cellPath.c_str() );
ccell << "V ALLIANCE : 6" << endl;

View File

@ -817,7 +817,7 @@ namespace {
namespace CRL {
void apParser ( const string& cellPath, Cell *cell )
void apParser ( const string cellPath, Cell *cell )
{
cmess2 << " " << tab << "+ " << cellPath << endl;

View File

@ -55,8 +55,8 @@ namespace CRL {
// -------------------------------------------------------------------
// functions.
void vstParser ( const string& cellPath, Cell* cell );
void vstDriver ( const string& cellPath, Cell* cell, unsigned int& saveState);
void vstParser ( const string cellPath, Cell* cell );
void vstDriver ( const string cellPath, Cell* cell, unsigned int& saveState);
}

View File

@ -614,7 +614,7 @@ void DumpConnectionList(ofstream &ccell, Instance*instance)
namespace CRL {
void vstDriver ( const string &cellPath, Cell *cell, unsigned int &saveState )
void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState )
{
::std::ofstream ccell ( cellPath.c_str() );
ccell << "entity " << cell->getName() << " is" << endl;

View File

@ -1244,7 +1244,7 @@ namespace CRL {
// -------------------------------------------------------------------
// Function : "vstParser()".
void vstParser ( const string& cellPath, Cell *cell )
void vstParser ( const string cellPath, Cell *cell )
{
cmess2 << " " << tab << "+ " << cellPath << endl; tab++;

View File

@ -59,8 +59,8 @@ namespace CRL {
// -------------------------------------------------------------------
// functions.
void bookshelfParser ( const string& cellPath, Cell* cell );
void bookshelfDriver ( const string& cellPath, Cell* cell, unsigned int& saveState);
void bookshelfParser ( const string cellPath, Cell* cell );
void bookshelfDriver ( const string cellPath, Cell* cell, unsigned int& saveState);
}

View File

@ -259,7 +259,7 @@ void DumpInstances(ofstream &ccell, Cell* cell) {
namespace CRL {
void bookshelfDriver( const string& cellPath, Cell *cell, unsigned int &saveState)
void bookshelfDriver( const string cellPath, Cell *cell, unsigned int &saveState)
{
::std::ofstream auxFile ( cellPath.c_str() );

View File

@ -1059,7 +1059,7 @@ void BKParser::LoadFromFile ( const string& cellPath, Cell* cell )
namespace CRL {
void bookshelfParser ( const string& cellPath, Cell *cell )
void bookshelfParser ( const string cellPath, Cell *cell )
{
cmess2 << " " << tab << "+ " << cellPath << endl;

View File

@ -12,6 +12,6 @@ namespace Hurricane {
}
namespace CRL {
void cifDriver(const std::string& file, Hurricane::Cell*, std::string& name, std::string& units, double& scale );
void cifDriver(const std::string file, Hurricane::Cell*, std::string& name, std::string& units, double& scale );
}
# endif

View File

@ -89,7 +89,7 @@ void CifQuery::goCallback(Go* go) {
} // namespace
namespace CRL {
void cifDriver(const string& filePath, Cell* cell, string& name, string& units, double& scale) {
void cifDriver(const string filePath, Cell* cell, string& name, string& units, double& scale) {
name = getString(cell->getName());
replace(name.begin(), name.end(), ' ', '_');
units = "micro";

View File

@ -56,10 +56,10 @@ namespace CRL {
// -------------------------------------------------------------------
// Typedefs.
typedef void ( LibraryParser_t )( const string& , Library*, Catalog& );
typedef void ( CellParser_t )( const string& , Cell* );
typedef void ( LibraryDriver_t )( const string& , Library *, Catalog& );
typedef void ( CellDriver_t )( const string& , Cell*, unsigned int& );
typedef void ( LibraryParser_t )( const string , Library*, Catalog& );
typedef void ( CellParser_t )( const string , Cell* );
typedef void ( LibraryDriver_t )( const string , Library *, Catalog& );
typedef void ( CellDriver_t )( const string , Cell*, unsigned int& );
// -------------------------------------------------------------------

View File

@ -167,7 +167,7 @@ bool LessNet::operator () ( Net* net1, Net* net2 ) {
void defDriver ( const string& cellPath, Cell *cell, unsigned int &saveState )
void defDriver ( const string cellPath, Cell *cell, unsigned int &saveState )
{
# if HAVE_LEFDEF && defined(LEF_ENABLED)
CDataBase* dataBase = GetCDataBase();

View File

@ -643,7 +643,7 @@ namespace {
namespace CRL {
void defParser ( const string& cellPath, Cell *cell )
void defParser ( const string cellPath, Cell *cell )
{
static unsigned int callNumber = 0;

View File

@ -76,9 +76,9 @@ namespace CRL {
// functions.
extern void CParsLEFTechno ( string fileTechno );
extern void lefParser ( const string& libPath, Library* lib, Catalog& catal );
extern void defParser ( const string& cellPath, Cell* cell );
extern void defDriver ( const string& cellPath, Cell* cell, unsigned int& saveState );
extern void lefParser ( const string libPath, Library* lib, Catalog& catal );
extern void defParser ( const string cellPath, Cell* cell );
extern void defDriver ( const string cellPath, Cell* cell, unsigned int& saveState );
} // End of CRL namespace.

View File

@ -642,7 +642,7 @@ namespace CRL {
// -------------------------------------------------------------------
// Function : "lefParser()".
void lefParser ( const string& libPath, Library* library, Catalog& catalog )
void lefParser ( const string libPath, Library* library, Catalog& catalog )
{
static int callNumber = 0;

View File

@ -33,7 +33,7 @@ using namespace Hurricane;
* Parse hierarchy spice file.
*/
void spiceParser ( const string& cellPath, Cell* cell )
void spiceParser ( const string cellPath, Cell* cell )
// ****************************************************
{
// recursiveDepth++;
@ -51,7 +51,7 @@ void spiceParser ( const string& cellPath, Cell* cell )
}
void spiceDriver ( const string& cellPath, Cell* cell, unsigned int& saveState)
void spiceDriver ( const string cellPath, Cell* cell, unsigned int& saveState)
// ****************************************************************************
{
CSpiceDriver driver(cell);

View File

@ -29,9 +29,9 @@ using std::string;
// That means this function create the logical view of
// those cells who's syntax is correct in the hierarchy.
// ******************************************************
void spiceParser ( const string& cellPath, Cell* cell );
void spiceParser ( const string cellPath, Cell* cell );
void spiceDriver ( const string& cellPath, Cell* cell, unsigned int& saveState);
void spiceDriver ( const string cellPath, Cell* cell, unsigned int& saveState);
}

View File

@ -130,7 +130,7 @@ void CSpiceDriver::_DumpEnds(ofstream& outfile)
}
void CSpiceDriver::Drive(const string& cellpath)
void CSpiceDriver::Drive(const string cellpath)
// *********************************************
{
ofstream outfile(cellpath.c_str());

View File

@ -59,7 +59,7 @@ class CSpiceDriver {
// Operators
// *********
public : void Drive(const string&);
public : void Drive(const string);
};

View File

@ -390,7 +390,7 @@ void CSpiceParser::_getEntierLine(string& bigbuf, ifstream& infile)
// If there isn't any error any more, create really the logical view
// of model.
// ******************************************************************
void CSpiceParser::Parse(const string& cellPath, Cell* cell)
void CSpiceParser::Parse(const string cellPath, Cell* cell)
// *********************************************************
{
CatalogProperty *sprop =

View File

@ -67,7 +67,7 @@ class CSpiceParser {
// Operations
// **********
public : void Parse(const string& , Cell*);
public : void Parse(const string , Cell*);
// Others
// ******