/**CFile****************************************************************
FileName [abcFunc.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Experimental procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcFunc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "acb.h"
#include "aig/miniaig/ndr.h"
#include "sat/cnf/cnf.h"
#include "sat/bsat/satStore.h"
#include "sat/satoko/satoko.h"
#include "map/mio/mio.h"
#include "misc/util/utilTruth.h"
#include "aig/gia/giaAig.h"
#include "base/main/main.h"
#include "base/cmd/cmd.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef enum {
ACB_NONE = 0, // 0: unused
ACB_MODULE, // 1: "module"
ACB_ENDMODULE, // 2: "endmodule"
ACB_INPUT, // 3: "input"
ACB_OUTPUT, // 4: "output"
ACB_WIRE, // 5: "wire"
ACB_BUF, // 6: "buf"
ACB_NOT, // 7: "not"
ACB_AND, // 8: "and"
ACB_NAND, // 9: "nand"
ACB_OR, // 10: "or"
ACB_NOR, // 11: "nor"
ACB_XOR, // 12: "xor"
ACB_XNOR, // 13: "xnor"
ACB_MUX, // 14: "_HMUX"
ACB_DC, // 15: "_DC"
ACB_UNUSED // 14: unused
} Acb_KeyWords_t;
static inline char * Acb_Num2Name( int i )
{
if ( i == 1 ) return "module";
if ( i == 2 ) return "endmodule";
if ( i == 3 ) return "input";
if ( i == 4 ) return "output";
if ( i == 5 ) return "wire";
if ( i == 6 ) return "buf";
if ( i == 7 ) return "not";
if ( i == 8 ) return "and";
if ( i == 9 ) return "nand";
if ( i == 10 ) return "or";
if ( i == 11 ) return "nor";
if ( i == 12 ) return "xor";
if ( i == 13 ) return "xnor";
if ( i == 14 ) return "_HMUX";
if ( i == 15 ) return "_DC";
return NULL;
}
static inline int Acb_Type2Oper( int i )
{
if ( i == 6 ) return ABC_OPER_BIT_BUF;
if ( i == 7 ) return ABC_OPER_BIT_INV;
if ( i == 8 ) return ABC_OPER_BIT_AND;
if ( i == 9 ) return ABC_OPER_BIT_NAND;
if ( i == 10 ) return ABC_OPER_BIT_OR;
if ( i == 11 ) return ABC_OPER_BIT_NOR;
if ( i == 12 ) return ABC_OPER_BIT_XOR;
if ( i == 13 ) return ABC_OPER_BIT_NXOR;
if ( i == 14 ) return ABC_OPER_BIT_MUX;
if ( i == 15 ) return ABC_OPER_TRI;
assert( 0 );
return -1;
}
static inline char * Acb_Oper2Name( int i )
{
if ( i == ABC_OPER_CONST_F ) return "const0";
if ( i == ABC_OPER_CONST_T ) return "const1";
if ( i == ABC_OPER_CONST_X ) return "constX";
if ( i == ABC_OPER_BIT_BUF ) return "buf";
if ( i == ABC_OPER_BIT_INV ) return "not";
if ( i == ABC_OPER_BIT_AND ) return "and";
if ( i == ABC_OPER_BIT_NAND ) return "nand";
if ( i == ABC_OPER_BIT_OR ) return "or";
if ( i == ABC_OPER_BIT_NOR ) return "nor";
if ( i == ABC_OPER_BIT_XOR ) return "xor";
if ( i == ABC_OPER_BIT_NXOR ) return "xnor";
if ( i == ABC_OPER_BIT_MUX ) return "mux";
if ( i == ABC_OPER_TRI ) return "_DC";
assert( 0 );
return NULL;
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Installs the required standard cell library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * pLibStr[25] = {
"GATE buf 1 O=a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE inv 1 O=!a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE and2 1 O=a*b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE and3 1 O=a*b*c; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE and4 1 O=a*b*c*d; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE or2 1 O=a+b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE or3 1 O=a+b+c; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE or4 1 O=a+b+c+d; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nand2 1 O=!(a*b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nand3 1 O=!(a*b*c); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nand4 1 O=!(a*b*c*d); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nor2 1 O=!(a+b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nor3 1 O=!(a+b+c); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nor4 1 O=!(a+b+c+d); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE xor 1 O=!a*b+a*!b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE xnor 1 O=a*b+!a*!b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE zero 0 O=CONST0;\n"
"GATE one 0 O=CONST1;\n"
};
char * pLibStr2[25] = {
"GATE buf 1 O=a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE inv 1 O=!a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE and2 1 O=a*b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE or2 1 O=a+b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nand2 1 O=!(a*b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE nor2 1 O=!(a+b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE xor 1 O=!a*b+a*!b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE xnor 1 O=a*b+!a*!b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
"GATE zero 0 O=CONST0;\n"
"GATE one 0 O=CONST1;\n"
};
void Acb_IntallLibrary( int f2Ins )
{
extern Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
Mio_Library_t * pLib;
int i;
// create library string
Vec_Str_t * vLibStr = Vec_StrAlloc( 1000 );
char ** ppLibStr = f2Ins ? pLibStr2 : pLibStr;
for ( i = 0; ppLibStr[i]; i++ )
Vec_StrAppend( vLibStr, ppLibStr[i] );
Vec_StrPush( vLibStr, '\0' );
// create library
pLib = Mio_LibraryReadBuffer( Vec_StrArray(vLibStr), 0, NULL, 0 );
Mio_LibrarySetName( pLib, Abc_UtilStrsav("iccad17.genlib") );
Mio_UpdateGenlib( pLib );
Vec_StrFree( vLibStr );
}
/**Function*************************************************************
Synopsis [Parse Verilog file into an intermediate representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Nam_t * Acb_VerilogStartNames()
{
Abc_Nam_t * pNames = Abc_NamStart( 100, 16 );
int i, NameId, fFound;
for ( i = 1; i < ACB_UNUSED; i++ )
{
NameId = Abc_NamStrFindOrAdd( pNames, Acb_Num2Name(i), &fFound );
assert( i == NameId && !fFound );
}
return pNames;
}
void Acb_VerilogRemoveComments ( char * pBuffer )
{
char * pTemp;
for ( pTemp = pBuffer; *pTemp; pTemp++ )
if ( pTemp[0] == '/' && pTemp[1] == '/' )
while ( *pTemp && *pTemp != '\n' )
*pTemp++ = ' ';
}
Vec_Int_t * Acb_VerilogSimpleLex( char * pFileName, Abc_Nam_t * pNames )
{
Vec_Int_t * vBuffer = Vec_IntAlloc( 1000 );
char * pBuffer = Extra_FileReadContents( pFileName );
char * pToken, * pStart, * pLimit = pBuffer + strlen(pBuffer);
if ( pBuffer == NULL )
return NULL;
Acb_VerilogRemoveComments( pBuffer );
pToken = strtok( pBuffer, " \n\r\t(),;=" );
while ( pToken )
{
int iToken = Abc_NamStrFindOrAdd( pNames, pToken, NULL );
if ( !strcmp(pToken, "assign") )
Vec_IntPush( vBuffer, ACB_BUF );
else
Vec_IntPush( vBuffer, iToken );
if ( iToken >= ACB_BUF && iToken < ACB_UNUSED )
{
for ( pStart = pToken; pStart < pLimit && *pStart != '\n'; pStart++ )
if ( *pStart == '(' )
break;
if ( *pStart == '(' )
{
pToken = strtok( pStart, " \n\r\t(),;=" );
continue;
}
}
pToken = strtok( NULL, " \n\r\t(),;=" );
}
ABC_FREE( pBuffer );
return vBuffer;
}
int Acb_WireIsTarget( int Token, Abc_Nam_t * pNames )
{
char * pStr = Abc_NamStr(pNames, Token);
return pStr[0] == 't' && pStr[1] == '_';
}
void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames )
{
Ndr_Data_t * pDesign = NULL;
Vec_Int_t * vInputs = Vec_IntAlloc(100);
Vec_Int_t * vOutputs = Vec_IntAlloc(100);
Vec_Int_t * vWires = Vec_IntAlloc(100);
Vec_Int_t * vTypes = Vec_IntAlloc(100);
Vec_Int_t * vFanins = Vec_IntAlloc(100);
Vec_Int_t * vCur = NULL;
int i, ModuleID, Token, Size, Count = 0;
assert( Vec_IntEntry(vBuffer, 0) == ACB_MODULE );
Vec_IntForEachEntryStart( vBuffer, Token, i, 2 )
{
if ( vCur == NULL && Token >= ACB_UNUSED )
continue;
if ( Token == ACB_ENDMODULE )
break;
if ( Token == ACB_INPUT )
vCur = vInputs;
else if ( Token == ACB_OUTPUT )
vCur = vOutputs;
else if ( Token == ACB_WIRE )
vCur = vWires;
else if ( Token >= ACB_BUF && Token < ACB_UNUSED )
{
Vec_IntPush( vTypes, Token );
Vec_IntPush( vTypes, Vec_IntSize(vFanins) );
vCur = vFanins;
}
else
Vec_IntPush( vCur, Token );
}
Vec_IntPush( vTypes, -1 );
Vec_IntPush( vTypes, Vec_IntSize(vFanins) );
// create design
pDesign = (Ndr_Data_t *)Ndr_Create( Vec_IntEntry(vBuffer, 1) );
ModuleID = Ndr_AddModule( pDesign, Vec_IntEntry(vBuffer, 1) );
// create inputs
Ndr_DataResize( pDesign, Vec_IntSize(vInputs) );
Vec_IntForEachEntry( vInputs, Token, i )
Ndr_DataPush( pDesign, NDR_INPUT, Token );
Ndr_DataAddTo( pDesign, ModuleID-256, Vec_IntSize(vInputs) );
Ndr_DataAddTo( pDesign, 0, Vec_IntSize(vInputs) );
// create outputs
Ndr_DataResize( pDesign, Vec_IntSize(vOutputs) );
Vec_IntForEachEntry( vOutputs, Token, i )
Ndr_DataPush( pDesign, NDR_OUTPUT, Token );
Ndr_DataAddTo( pDesign, ModuleID-256, Vec_IntSize(vOutputs) );
Ndr_DataAddTo( pDesign, 0, Vec_IntSize(vOutputs) );
// create targets
Ndr_DataResize( pDesign, Vec_IntSize(vWires) );
Vec_IntForEachEntry( vWires, Token, i )
if ( Acb_WireIsTarget(Token, pNames) )
Ndr_DataPush( pDesign, NDR_TARGET, Token ), Count++;
Ndr_DataAddTo( pDesign, ModuleID-256, Count );
Ndr_DataAddTo( pDesign, 0, Count );
// create nodes
Vec_IntForEachEntry( vInputs, Token, i )
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
if ( (Token = Abc_NamStrFind(pNames, "1\'b0")) )
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST_F, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
if ( (Token = Abc_NamStrFind(pNames, "1\'b1")) )
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST_T, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
if ( (Token = Abc_NamStrFind(pNames, "1\'bx")) )
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST_X, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
Vec_IntForEachEntryDouble( vTypes, Token, Size, i )
if ( Token > 0 )
{
int Output = Vec_IntEntry(vFanins, Size);
int nFanins = Vec_IntEntry(vTypes, i+3) - Size - 1;
int * pFanins = Vec_IntEntryP(vFanins, Size+1);
Ndr_AddObject( pDesign, ModuleID, Acb_Type2Oper(Token), 0, 0, 0, 0, nFanins, pFanins, 1, &Output, NULL ); // many fanins
}